IPv6 tcp socket HBH扩展报头设置
一、扩展报头粘性选项介绍
根据RFC 3542中的说明,存在两种机制可以用于发送携带HBH扩展报头的IPv6数据包,分别为:
- 使用ancillary data,可以为单个数据包指定扩展报头的选项内容;
- 使用setsockopt函数,可以为一个socket指定扩展报头的选项内容。设置完毕后,可以使该socket发出的所有数据包都携带指定的选项内容,所以也被称为粘性选项("sticky" options)。再次调用setsockopt函数后,可以对扩展报头的选项内容进行更新。
二、设置函数
设置HBH扩展报头的粘性选项需要依次使用4种函数,分别为inet6_opt_init(),inet6_opt_append(),inet6_opt_set_val(),inet6_opt_finish(),且其中3种需要被调用2次。
2.1变量定义
#define OPT_X 0x3c // 定义TLV选项类型,此处自定义为0x3c
void* extbuf; // extension buffer,扩展报头缓存指针
socklen_t extlen; // extension length,扩展报头长度
int currentlen; // 当前长度
void* databuf; // data buffer,扩展报头数据部分缓存指针
int offset; // 偏移
uint32_t value4; // 4字节数据变量
uint64_t value8; // 8字节数据变量
int datalen; // TLV选项数据长度
2.2 第一次调用设置函数
第一次调用函数,用于获得扩展报头长度,为扩展报头分配内存空间,以便第二次调用时存放数据。
2.2.1 inet6_opt_init ()
int inet6_opt_init(void *extension_buffer,
socklen_t extension_length)
该函数返回扩展报头所需的字节数。
currentlen = inet6_opt_init(NULL, 0);
第一次调用该函数,用于开始计算扩展报头大小。
2.2.2 inet6_opt_append()
int inet6_opt_append(void *extension_buffer,
socklen_t extension_length,
int offset,
uint8_t option_type,
socklen_t option_length,
uint32_t alignment,
void **data_bufferp)
该函数返回添加了新TLV选项和对齐后的扩展报头新长度。
currentlen = inet6_opt_append(NULL, 0, currentlen, OPT_X, datalen, 8, NULL);
第一次调用该函数,根据准备设置的TLV选项的类型、数据长度等信息,更新扩展报头长度。OPT_X表示需要设置的TLV选项类型,datalen表示设置该选项的数据部分长度为12字节,8表示该TLV选项是8字节对齐。
2.2.3 inet6_opt_finish()
int inet6_opt_finish(void *extension_buffer,
socklen_t extension_length,
int offset)
该函数返回IPv6扩展报头增加填充字节后的长度,使扩展报头满足字节对齐要求。
currentlen = inet6_opt_finish(NULL, 0, currentlen);
第一次调用该函数,计算增加了填充选项(Pad1、PadN)后的长度,使扩展报头长度满足字节对齐要求。
2.3第二次调用设置函数
首先,应根据第一次调用3种函数后计算得到的扩展报头长度对变量进行更新:
extlen = currentlen; // 更新扩展报头长度
extbuf = malloc(extlen); // 为扩展报头分配内存空间
2.3.1 inet6_opt_init()
currentlen = inet6_opt_init(extbuf, extlen);
第二次调用该函数,基于extlen初始化extbuf。
此时extbuf指向的扩展报头内存空间中,前2字节为HBH头部,第一字节表示下一头部类型,函数暂不设置;第二字节表示扩展报头长度,函数通过extlen设置。
2.3.2 inet6_opt_append()
currentlen = inet6_opt_append(extbuf, extlen, currentlen, OPT_X, datalen, 8, &databuf);
第二次调用该函数,为扩展报头添加TLV选项,并使databuf指向扩展报头内存空间中的数据部分的起始字节处。
此时extbuf指向的扩展报头内存空间中,第三字节被函数填充为TLV选项类型OPT_X,第四字节为TLV选项数据长度,函数通过datalen设置,故databuf实际指向第5字节处。(注意,此处简化分析,实际情况可能并非从第三字节开始填充TLV选项,因为系统会先根据扩展报头长度和对齐要求填充Pad1或PanN选项)。
重复使用该函数,可以为同一个扩展报头添加多个TLV选项。
2.3.3 inet6_opt_set_val()
offset = 0;
value4 = 0x12345678; // 为4字节变量赋值
offset = inet6_opt_set_val(databuf, offset,&value4, sizeof(value4));
value8 = 0x0102030405060708; // 为8字节变量赋值
offset = inet6_opt_set_val(databuf, offset,&value8, sizeof(value8));
两次调用该函数,分别将value4和value8的数据填入databuf指向的扩展报头内存空间的数据部分。
2.3.4 inet6_opt_finish()
currentlen = inet6_opt_finish(extbuf, extlen, currentlen);
第二次调用该函数,系统根据扩展报头长度和对齐要求在扩展报头内存空间中填充Pad1或PanN选项,使满足对齐要求。
2.4 setsockopt()
int setsockopt(int socket_descriptor,
int level,
int option_name,
char *option_value,
int option_length)
该函数用于设置socket。
setsockopt(m_sock, IPPROTO_IPV6,IPV6_HOPOPTS,extbuf, currentlen);
在上述函数调用完毕后,为socket设置HBH扩展头,设置level为IPPROTO_IPV6;option_name为IPV6_HOPOPTS;extbuf指向扩展报头内存空间,使socket能访问HBH扩展头数据。
三、扩展报头内容修改
在依次调用inet6_opt_init(),inet6_opt_append(),inet6_opt_set_val(),inet6_opt_finish()和setsockopt函数后,socket发出的数据包都将带有设置好的HBH扩展报头。
如果需要修改扩展报头内容,而不改变数据长度,再次调用inet6_opt_set_val()和setsockopt即可;如果需要修改数据长度,则需要全部重新设置。在重新设置完成后,socket发出的数据包的HBH扩展报头都会被更新。
参考文献:
IBM Documentation
RFC 3542 - Advanced Sockets Application Program Interface (API) for IPv6
IPv6 tcp socket HBH扩展报头设置相关推荐
- 《IPv6技术精要》一2.4 扩展报头
本节书摘来自异步社区<IPv6技术精要>一书中的第2章,第2.4节,作者[美]Rick Graziani,更多章节内容可以访问云栖社区"异步社区"公众号查看 2.4 扩 ...
- C# 的tcp Socket设置自定义超时时间
简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...
- linux网络编程IPv6socket,简单的IPv6 UDP/TCP socket编程 -- 两台Linux实现简单的ipv6通信...
配置: 1.两台linux用网线直接相连 2.手动配置两台linux的ipv6地址为: ifconfig eth0 add 2001:da8:e000::1:1:1 ifconfig eth0 add ...
- IPv6之初使用,及IPv4与IPv6的socket通信
1.IPv6概念 IPv6是InternetProtocol Version 6的缩写.IPv6是IETF(互联网工程任务组,InternetEngineering Task Force)设计的用于替 ...
- python 实现TCP socket通信和 HTTP服务器、服务器和客户端通信python实例
python 实现TCP socket通信和 HTTP服务器.服务器和客户端通信实例 socket是什么? 服务器和客户端通信的流程 python 实现TCP socket通信例子 关于Host和PO ...
- pdu报头内容_发送具有分段和打包扩展报头的macpdu的装置及其方法
专利名称:发送具有分段和打包扩展报头的mac pdu的装置及其方法 技术领域: 本发明涉及一种移动通信系统,并且更具体的,涉及ー种用于传送具有分段&打包扩展报头的MAC PDU (媒体访问控制 ...
- 转Go语言TCP Socket编程
授权转载: Tony Bai 原文连接: https://tonybai.com/2015/11/17/tcp-programming-in-golang/ Golang的主要 设计目标之一就是面向大 ...
- golang TCP Socket编程
Golang的主要 设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不可少也是至关重要的一部分.在日常应用中,我们也可以看到Go中的net以及其subdirectories下的包均 ...
- 【Java 网络编程】TCP 数据传输示例 ( 客户端参数设置 | 服务器端参数设置 | ByteBuffer 存放读取数据类型 )
文章目录 I 客户端代码示例 II 服务器端代码示例 III 运行结果 I 客户端代码示例 import java.io.IOException; import java.io.InputStream ...
最新文章
- R语言ggplot2可视化:jupyter中设置全局图像大小、jupyter中自定义单个ggplot2图像结果的大小
- 索引中丢失 IN 或 OUT 参数:: 103,解决办法
- GPU端吊打RegNet、EfficientNet的强悍担当:GENet
- JVM参数调优,无停滞实践
- 百度回应“出售他人隐私”报道:从未开展此类业务
- [.net]c#登陆实现验证码-图形编程
- 微信团队分享:微信支付代码重构以及软件架构上的思考
- Linux之flash流媒体服务器red5安装
- 变更日志 批准的变更请求 收尾流程 原型法 名义小组 习题
- linux 查找py文件命令_Linux常用命令(一)
- WOX配置常用搜索引擎
- 解决windows电脑蓝屏的方法
- Android强行进阶:为何大厂APP如微信、支付宝、淘宝、手Q等只适配了armeabi-v7a/armeabi?
- 我们无法创建新分区。【错误:0x80042468】
- 学习OpenCV 函数方法结构总结
- 基于Redis实现查找附近的人
- 2019校招宜信JAVA研发面经
- Android APP连接电脑数据库(以SQL Server为例)
- SAP BASIS ADM100 中文版 Unit 5(4)
- 第八课——细述QQ与TIM的不同之处
热门文章
- vue 拖拽组件github网址
- 概率密度函数、分布函数区别
- 单分支结构与双分支结构与多分支结构
- 批处理获取本机IP(局域网)及MAC地址
- 佰马科技亮相中国通信展,参加智慧杆最受欢迎企业联展
- 利用Scrapy框架爬取前途无忧招聘信息
- 剑桥计算机通用英语优学院,优学院《剑桥计算机通用英语》答案2020中国大学《光学(王海艳)》查询答案...
- python口号_1947年10月10日,中国人民解放军总部发表宣言,提出的口号是( )
- 2020武汉大学计算机学院夏令营面经
- 人工智能:到底是天使还是恶魔?