openswan中的in_struct和out_struct函数

openswan中的in_struct和out_struct函数

1. 花絮

​ 有什么比openswan中的in_struct和out_struct更让人难以理解的呢??? 如果存在的话,那就是:女朋友为啥又生气了?

img

算了,不管了,今天我是找不到她生气的原因了;还是把openswan中的in_struct()函数整理下吧,感觉这个更容易些
在这里插入图片描述

在学习openswan源码的过程中,有两个函数是想逃不能逃的,但是有很难看懂它是怎么个原理,它的功能很明确,但是就算如此,还是看不懂它的原理。我看这个接口花了很长的时间。哎,没办法,基础有点菜。下面就把个人的心得分享下:

2. in_struct代码实现分析

在源代码中in_struct和out_struct都有一段较为详细的注释:

/* "parse" a network struct into a host struct.
 *
 * This code assumes that the network and host structure
 * members have the same alignment and size!  This requires
 * that all padding be explicit.
 *
 * If obj_pbs is supplied, a new pb_stream is created for the
 * variable part of the structure (this depends on their
 * being one length field in the structure).  The cursor of this
 * new PBS is set to after the parsed part of the struct.
 *
 * This routine returns TRUE iff it succeeds.
 */

这里对in_struct进行描述:它的功能也比较明确:

将网络字节序结构体转换为主机字节序结构体

这里假设网络结构体和主机结构体拥有相同的对齐方式和大小, 这要求他们所有的填充字节都是明确的。

如果参数obj_pbs是非空,则会创建一个新的pb_stream结构。它用来描述inssd的部分,但是cur指针是指向已经解析完毕的数据后后一个字节。

操作成功返回TRUE

是的,它转换的是结构体,而不是单个的short类型或者int类型。这样处理更加方便,模块化。简单的说:

htonl(), htons()分别转换的为四个字节,两个字节类型的变量,而in_struct(), out_struct()一次性转换一个结构体。只要你传入的结构体描述信息(struct_desc)正确就可以


也许我们对这个种方式不习惯,但是它的好处大大滴。既然使用了人家代码,那就接收人家的规则。


很多刚开始看的人不明白为什么要使用“obj_pbs”形参,既然解析完毕了为什么还要保存该信息呢???

在这里插入图片描述

实际上这个操作在变长的载荷中是必须的,因为变长部分数据并没有被转换到struct_ptr中。下面慢慢说明:

我是直接在源码上进行的注释:

/****************************************************
* 功能: 将网络字节序结构体转化为主机字节序结构体
* struct_ptr:  解析后的输出数据
* sd        :  描述信息			
* ins       :  输入的网络字节序数据流
* obj_pbs   :  指向该结构后面尚未解析的ins数据部分
*****************************************************/

bool
in_struct(void *struct_ptr, struct_desc *sd
, pb_stream *ins, pb_stream *obj_pbs)
{
   
    err_t ugh = NULL;
    u_int8_t *cur = ins->cur;/*待解析数据开始*/
	/*确保有待解析的数据大小足够,否则无法成功解析为sd描述的大小*/
    if (ins->roof - cur < (ptrdiff_t)sd->size)
    {
   
        ugh = builddiag("not enough room in input packet for %s"
                        " (remain=%li, sd->size=%zu)"
                        , sd->name, (long int)(ins->roof - cur), sd->size);

    }
    else
    {
   
    	/*root指向待解析数据的末尾*/
	u_int8_t *roof = cur + sd->size;    /* may be changed by a length field *//*未考虑变长属性*/
	u_int8_t *outp = struct_ptr;/*outp指向输出结构体*/
	bool immediate = FALSE;
	field_desc *fp;

	for (fp = sd->fields; ugh == NULL; fp++)
	{
   
	    size_t i = fp->size;
	    /*passert条件成立,继续执行;不成立,直接退出*/
	    passert(ins->roof - cur >= (ptrdiff_t)i);
	    passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
	    passert(outp - (cur - ins->cur) == struct_ptr);/*解析长度相同*/

	    switch (fp->field_type)
	    {
   
	    case ft_mbz:	/* must be zero *//*全零域,*/
		for (; i != 0; i--)
		{
   
		    if (<
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叨陪鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值