利用p4实现ipv6转发实验
写在前面
只是作为一个入门p4的实验尝试,借用了一些即成的运行代码。
p4代码
/**p4_16,v1_model**/
#include<core.p4>
#include<v1model.p4> const bit<> TYPE_IPV6 = 0x08DD;//ipv6在以太网中的id /*HEADERS*/ typedef bit<> egressSpec_t;
typedef bit<> macAddr_t; header ethernet_t{
macAddr_t dstAddr;
macAddr_t srcAddr;
bit<> etherType;
} header ipv6_t{
bit<> version;
bit<> trafficClass;
bit<> flowLabel;
bit<> payLoadLen;
bit<> nextHdr;
bit<> hopLimit;
bit<> srcAddr;
bit<> dstAddr;
} struct metadata{
} struct headers{
ethernet_t ethernet;
ipv6_t ipv6;
} /*PARSER*/ parser MyParser(packet_in packet,out headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata){
state start{
transition parse_ethernet;//start开始先以底层eth解析
} state parse_ethernet{
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType){
TYPE_IPV6:parse_ipv6;//转至ipv6解析
default:accept;
}
} state parse_ipv6{
packet.extract(hdr.ipv6);
transition accept;
}
} /*CHECKSUM VERIFICATION*/ control MyVerifyChecksum(inout headers hdr,inout metadata meta){
apply{}
} /*INGRESS PROCESSING*/ control MyIngress(inout headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata){
action drop(){
mark_to_drop();//将要丢弃的包标记为丢弃
} action ipv6_forward(macAddr_t dstAddr,egressSpec_t port){
standard_metadata.egress_spec = port;
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
hdr.ethernet.dstAddr = dstAddr;
hdr.ipv6.hopLimit = hdr.ipv6.hopLimit - ;//这个类似ipv4中ttl,为0时就超时
} table ipv6_lpm{
key = {
hdr.ipv6.dstAddr: lpm;//lpm是最长前缀匹配,exact完全匹配,ternary三元匹配
} actions = {
ipv6_forward;//转发
drop;//丢弃
NoAction;//空动作
} size = ;//流表项容量 default_action = drop();//table miss则丢弃
} apply{
if(hdr.ipv6.isValid()){
ipv6_lpm.apply();
}
}
} /*EGRESS PROCESSING*/ control MyEgress(inout headers hdr,inout metadata meta,inout standard_metadata_t standard_metadata){
apply{}
} /*CHECKSUM COMPUTATION*/ control MyComputeChecksum(inout headers hdr,inout metadata meta){
apply{}
} /*DEPARSER*/ control MyDeparser(packet_out packet,in headers hdr){
apply{
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv6);
}
} /*SWITCH*/ V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
)main;
实验拓扑
这里实验的拓扑用来最简单的一个交换机下挂两个主机,交换机是bmv2。其json文件书写如下: 交换机s1的流表项通过s1-commands.txt文件定义。
{
"program": "ipv6_forward.p4",
"language": "p4-16",
"targets": {
"multiswitch": {
"auto-control-plane": true,
"cli": true,
"pcap_dump": true,
"bmv2_log": true,
"links": [["h1", "s1"], ["h2", "s1"]],
"hosts": {
"h1": {
},
"h2": {
}
},
"switches": {
"s1": {
"entries": "s1-commands.txt"
}
}
}
}
}
在s1-commans.txt文件中做如下定义:
table_set_default ipv6_lpm drop
table_add ipv6_lpm ipv6_forward fe80::5678/128 => 00:04:00:00:00:02 2
table_add ipv6_lpm ipv6_forward fe80::1234/128 => 00:04:00:00:00:01 1
将其流表项画出来如下:
收发包脚本代码
鉴于对python socket发包代码不是那么了解,所以套用了一部分模板做了修改。
send.py
import argparse
import sys
import socket
import random
import struct from scapy.all import sendp, send, get_if_list, get_if_hwaddr
from scapy.all import Packet
from scapy.all import Ether, IPv6, UDP def get_if():
ifs=get_if_list()
iface=None
for i in get_if_list():
if "eth0" in i:
iface=i
break;
if not iface:
print "Cannot find eth0 interface"
exit(1)
return iface def main(): if len(sys.argv)<3:
print 'pass 3 arguments:<source> <destination> "<message>"'
exit(1)
saddr = sys.argv[1]
addr = sys.argv[2]
iface = get_if() print "sending on interface %s to %s" % (iface, str(addr))
pkt = Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff') / IPv6(src=saddr,dst=addr) / UDP(dport=4321, sport=1234) / sys.argv[3]
pkt.show2()
sendp(pkt, iface=iface, verbose=False) if __name__ == '__main__':
main()
receive.py
import sys
import struct
import os from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr
from scapy.all import Packet, IPOption
from scapy.all import ShortField, IntField, LongField, BitField, FieldListField, FieldLenField
from scapy.all import IPv6, TCP, UDP, Raw
from scapy.layers.inet import _IPOption_HDR def get_if():
ifs=get_if_list()
iface=None
for i in get_if_list():
if "eth0" in i:
iface=i
break;
if not iface:
print "Cannot find eth0 interface"
exit(1)
return iface class IPOption_MRI(IPOption):
name = "MRI"
option = 31
fields_desc = [ _IPOption_HDR,
FieldLenField("length", None, fmt="B",
length_of="swids",
adjust=lambda pkt,l:l+4),
ShortField("count", 0),
FieldListField("swids",
[],
IntField("", 0),
length_from=lambda pkt:pkt.count*4) ]
def handle_pkt(pkt):
print "got a packet"
pkt.show2()
#hexdump(pkt)
sys.stdout.flush() def main():
ifaces = filter(lambda i: 'eth' in i, os.listdir('/sys/class/net/'))
iface = ifaces[0]
print "sniffing on %s" % iface
sys.stdout.flush()
sniff(filter="udp and port 4321",iface = iface,
prn = lambda x: handle_pkt(x)) if __name__ == '__main__':
main()
测试
./run.sh
//在mininet cli中
xterm h1 h2
//在h2中
./receive.py
//在h1中
./send.py fe80::1234 fe80::5678 "Hello p4!"
结果如下:
牢骚
第一次尝试构建p4相关的实验,了解了一部分p4的语法,以及一些的工作原理,也发掘出一部分并未了解的知识内容待后续去琢磨学习。过程有很多不完美,结果也有很多不完美,虽然现在也不满足,但是寒假也快结束了。
利用p4实现ipv6转发实验的更多相关文章
- SSH的本地、远程、动态端口转发实验笔记
SSH端口转发 SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据.但是,SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务.这一 ...
- 哈工大 计算机网络 实验三 IPv4 分组收发实验&IPv4 分组转发实验
计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 IPv4 分组收发实验&IPv4 分组转发实验 实验目的: (注:实验报告模板中的各项内容仅供参考,可依照实际实验情况进 ...
- 老毛子 Padavan 路由器固件开启教育网 IPv6 并实现IPv6转发
老毛子 Padavan 路由器固件开启教育网 IPv6 并实现IPv6转发 文章目录[隐藏] 一.开启opt环境 二.开启 WAN 端 IPv6 三.安装并运行 6relayd 四.开机自动安装并配置 ...
- 利用IIS应用请求转发ARR实现IIS和tomcat整合共用80端口
现在网上流传的实现iis和tomcat共享80端口的方法是基于isapi_redirect插件实现的, 我的实现方法不同, 原理相似,具有更好的优点. 先说下基于isapi_redirect缺点,ja ...
- 利用php设置url转发 - 解决空间不提供子目录绑定功能的问题
由于很多新手都是使用的虚拟空间都是最便宜的那种,这空间一般不支持子目录绑定.但是很多朋友又想设置几个不同的二级域名访问不同的网站程序.于是大家找到了域名url转发,但是由于国家政策的原因,许多服务商暂 ...
- 利用iptables做端口转发
需求背景: A与C不在同一网段无法直接访问,而A和B,C和B可以互通.现需要A借助B访问C的3306端口. 解决方案: 利用iptables配置规则,实现端口转发. 具体操作: 在B上开启端口转发功能 ...
- 利用binlogserver恢复单表实验【转】
使用场景 每次开启binlogserver 指定了mysql-bin.0000XX 后都会从该点从头进行传输一次 创建binlogserver [root@mysql-zst3 binlogserve ...
- 关于利用GPG加解密的实验
GnuPG(GNU Privacy Guard,简称:GPG)为一款免费开源的使用非对称密钥加密(asymmetric cryptography)之软件,最初由Werner Koch开发,该软件使用非 ...
- 利用iptables做网络转发
常见的网络拓扑图结构如下: 但是内网服务器偶尔有上网需求,比如yum工具,wget文件.而我们又不能让重要业务直接暴露在公网上. 好用的安全策略有:三层交换机.路由器做nat映射,防火墙做安全策略. ...
随机推荐
- java Clob类型 转String
1.我的数据库是oracle11g 遇到取出来的字段是clob类型,但是所需要的是string类型,写一个转换函数就可以解决问题了. // Clob类型 转String public String C ...
- vue数组赋值
在使用vue开发移动端项目过程中,统一数组在对多个变量赋值时:希望一个数组的改变不影响另外一个数组,此时可以使用如下方式实现: let arr = [] let a1 = JSON.parse(JSO ...
- 浅淡 RxJS WebSocket
const open$ = new Subject(); const ws = webSocket({ url: 'wss://echo.websocket.org', openObserver: o ...
- grep基础用法详解
适合初学linux的人学得比较凌乱的人看这个也能理理思路学得更系统,节约你的学习时间,提高效率,但是思维导图的作用是帮人理清思路不会迷失在细节中,细节补充学习请参考https://www.cnblog ...
- less的在线安装
首先打开命令行窗口windonws+r输入cmd回车 1.确认是安装了node和less,在命令行输入“node -v”回车确认node是否安装,有版本信息则安装了,输入“lessc -v”回车确认l ...
- cookie,session,token
发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议, 就是请求加响应, 尤其是我不用 ...
- MongoDB数据库 : 管道,用户管理,副本集等
聚合(aggregate): db.集合.aggregate([{管道:{表达式}}]) db.集合.aggregate([ {管道1:{表达式1}}, {管道2:{表达式2}}, ... ...]) ...
- 使用抓包工具pproxy
下载地址:https://github.com/hidu/pproxy 一.下载后解压 二.打开pproxy.exe 三.手机连接wifi,设置wifi,代理改为手动,输入代理主机ip,代理主机端口. ...
- PTA(BasicLevel)-1007素数对猜想
一 问题描述-素数对 让我们定义素数差dn为:dn=pn+1−pn,其中pi是第i个素数.显然有d1=1,且对于n>1有dn是偶数.“素数对猜想”认为“ ...
- 20155204 2016-2017-2《Java程序设计》课程总结
20155204 2016-2017-2<Java程序设计>课程总结 目录 作业链接汇总 作业总结 实验报告链接汇总 代码托管链接 课堂项目实践 学习经验 问卷调查 链接二维码 (按顺序) ...