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
[email protected]:~$ 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實驗
本次實驗拓撲圖如下: 假設 Openvswitch switch1是一個帶有NAT功能的路由器,H1 的IP地址為 192.168.1.10,MAC地址為:00:00:00:00:00:01, H2 的IP地址為 10.0.0.1 MAC 地址為
Kafka學習(三)簡單例項(可以簡單做測試)
java客戶端連線kafka簡單測試 本案例kafka版本是kafka_2.11-0.9.0.1,用java來實現kafka生產者、消費者的示例 在測試的過程中遇到的特別的問題以及解決辦法,其他小問題就不一一列舉了。 1 . 使用kafka-clients進行測試,maven依賴
docker 基礎教程-入門:(三)--簡單製作映象
前言 一般情況下,我們中直接使用docker官網的庫,就可以找到我們日常開發中需要的映象,比如:ubuntu、tomcat、apache、nginx、php、mysql、redi
Go語言學習(三) 簡單比特幣挖礦類實現
//utils.go package main import ( "bytes" "encoding/binary" "log" ) func IntToHex(num int64)[]byte{ buff:=new(bytes.Buffer) //開闢記憶體,
學習筆記(三) 簡單的狀態模式&FSM有限狀態機框架的實現(二)
之前釋出的那篇部落格可能說的並是不非常清楚,所以整理了一下,也參考了一些文件,於是又寫了一篇總結。 一、有限狀態機FSM的要點 1、擁有一組狀態,並且可以再這組狀態之間進行切換。 2、狀態機同時只能存在一個狀態,英雄不能能同時處於跳躍和站立。而防止這一點就是使用
scrapy專利爬蟲(三)——簡單實際操作
scrapy專利爬蟲(三)——簡單實際操作 確定連結 在chrome中開啟審查元素中的network選項,檢視查詢專利時傳送的請求。觀察後發現在每次查詢的時候,瀏覽器都會先發送兩條請求給伺服器。 傳送相關請求 經過觀察發現,網站的查詢流程是 先發送不帶引
R基礎學習(三)-- 簡單練習(shiny+mysql+barplot)
user observe 實現 tle plot rstudio names eat lag 測試環境:win10+RStudio 提前準備: install.packages(‘shiny‘) install.packages(‘RMySQL‘) 數據表準備:
Xilinx ZYNQ 7000+Vivado2015.2系列(三)之HelloWorld實驗(最小系統)(純PS)
前言: 使用的板子是zc702。用Vivado的IP核搭建最小系統,包括ARM核(CPU xc7z020),DDR3(4×256M),一個UART串列埠(Mini USB轉串列埠),純PS,通過串列埠打印出HelloWorld,工程雖小,五臟俱全,算是一種朝聖。配置要和板子
java學習之Swing篇(三)——簡單畫板的實現v1.0
畫板功能實現: 1、直線、矩形、橢圓、多邊形、曲線等基本圖形的繪製; 2、多種顏色可選; 3、橡皮檫採用加粗畫筆,另新增一鍵清屏功能; 4、重繪功能; 5、多邊形採用兩種方式自動閉合:一種滑鼠雙擊閉合,一種為切換其它圖形自動閉合; 6、採用邊界佈局。 圖形效果:
tinyxml(三)——簡單的生成和解析示例
#include <stdio.h> #include <string> using namespace std; #include "../tinyxml/tinyxml.
CANoe 入門 Step by step系列(三)簡單例子的剖析
最好的學習方式是什麼?模仿。有人會問,那不是山寨麼?但是我認為,那是模仿的初級階段,當把別人最好的設計已經融化到自己的血液裡,變成自己的東西,而靈活運用的時候,才是真正高階階段。正所謂畫虎畫皮難畫骨。但初級階段仍然是必須經歷的過程,他會使你在達到高階階段的過程中少走很多
(三)簡單工廠模式詳解
作者:zuoxiaolong8810(左瀟龍),轉載請註明出處。 上一章我們著重討論了代理模式,以及其實現原理,相信如果你看完了整篇博文,應該就對代理模式很熟悉了。 本章我們討論簡單工廠模式,LZ當初不小
Java實驗--基於Swing的簡單的歌曲信息管理系統(三)
img dbo check clas str http 按鈕 cancel uuid 轉載請註明出處,上一篇《Java實驗--基於Swing的簡單的歌曲信息管理系統(二)》介紹了項目的目錄結構和Dao層,本篇主要講解界面的繪制和業務層Service。 登錄界面 登錄
keepalived簡單實驗(三)vrrp_script中要不要寫weight欄位
今天在公司看到keepalived主備機器上的keepalived配置檔案的vrrp_scrip段中都沒有weight欄位,直接貼圖吧: master的配置檔案: backup的配置檔案: 指令碼的內容: 我在想,這樣寫就算master那邊的vrrp_scrip
Java對數組的操作(三)—比較兩個數組中的元素是否同樣的最簡單方法
con data println test popu pan equal main spa 呵呵呵,實現Java比較兩個數組中的元素是否同樣的功能你是怎麽做的?看以下最簡單方法: import java.util.Arrays;
關於wamp的HTML, PHP, mysql 三者的操作與聯系 - mysql簡單配置(三)
長度 -1 logs 建議 用戶 不用 自帶 .com upd 上一章講完HTML與PHP之間的傳值方法,這一章將wamp中mysql的使用,為下一章PHP調用數據準備。 再次說明作者的wamp版本是3.0.6 64bit 打開wamp自帶的mysql試圖數據庫
計算機網絡基礎(三)—交換機配置的簡單命令
交換機配置1、網絡設備的構成硬件:內存-RAM — 隨即讀取存儲器 CPU flash-硬盤 ROM — read only memory 只讀存儲器 nvram— 非易失性內存軟件: 系統文件 ---
redis 實驗(三)主從復制
系統/運維 Linux 先在主機啟動redis-server再開一個6380的端口redis-server --port 6380 --slaveof 127.0.0.1 6379單機雙實例輸入info看replication狀態主機master role另外一個實例主實例存取正常,從實例只能讀取無法
ELK 實驗(三)安裝Kibana
大數據 其他 下載安裝linux 包wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.3-linux-x86_64.tar.gzshasum -a 512 kibana-6.2.3-linux-x86_64.tar.gz tar
用最簡單的例子說明設計模式(三)之責任鏈、建造者、適配器、代理模式、享元模式
def dap CA 抽象 創建 tcl cte clas eth 責任鏈模式 一個請求有多個對象來處理,這些對象是一條鏈,但具體由哪個對象來處理,根據條件判斷來確定,如果不能處理會傳遞給該鏈中的下一個對象,直到有對象處理它為止 使用場景 1)有多個對象可以處理同