免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

关于构造Http Response包的问题 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2008-09-10 23:00 |显示全部楼层
我用的是2.6.26,skb_copy_expand代码有点不一样
/**
*        skb_copy_expand        -        copy and expand sk_buff
*        @skb: buffer to copy
*        @newheadroom: new free bytes at head
*        @newtailroom: new free bytes at tail
*        @gfp_mask: allocation priority
*
*        Make a copy of both an &sk_buff and its data and while doing so
*        allocate additional space.
*
*        This is used when the caller wishes to modify the data and needs a
*        private copy of the data to alter as well as more space for new fields.
*        Returns %NULL on failure or the pointer to the buffer
*        on success. The returned buffer has a reference count of 1.
*
*        You must pass %GFP_ATOMIC as the allocation priority if this function
*        is called from an interrupt.
*/
struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
                                int newheadroom, int newtailroom,
                                gfp_t gfp_mask)
{
        /*
         *        Allocate the copy buffer
         */
        struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom,
                                      gfp_mask);
        int oldheadroom = skb_headroom(skb);
        int head_copy_len, head_copy_off;
        int off;

        if (!n)
                return NULL;

        skb_reserve(n, newheadroom);

        /* Set the tail pointer and length */
        skb_put(n, skb->len);

        head_copy_len = oldheadroom;
        head_copy_off = 0;
        if (newheadroom <= head_copy_len)
                head_copy_len = newheadroom;
        else
                head_copy_off = newheadroom - head_copy_len;

        /* Copy the linear header and data. */
        if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off,
                          skb->len + head_copy_len))
                BUG();

        copy_skb_header(n, skb);

        off                  = newheadroom - oldheadroom;
        n->csum_start       += off;
#ifdef NET_SKBUFF_DATA_USES_OFFSET
        n->transport_header += off;
        n->network_header   += off;
        n->mac_header            += off;
#endif

        return n;
}

论坛徽章:
0
2 [报告]
发表于 2008-09-10 23:12 |显示全部楼层
原帖由 Godbach 于 2008-9-5 10:55 发表
基本上搞清楚了这个函数,当tailroom的长度小于需要追加数据时,函数skb_copy_expand将重新申请buffer,其大小为原先skb的headroom大小+ skb->len+ 需要追加数据的长度,相当于把原先的tailroom扩大到等于追加数 ...


从代码来看,skb_copy_expand上来就重新分配了一个struct sk_buff *,
长度等于原来的长度加上newheadroom再加上newtailroom,是不是有点浪费?
难道不应该是skb->len + newheadroom + newtailroom - skb_headroom(skb)- 原来的newtailroom 吗?

如果头部保持不变的话,那么newheadroom取值应该等于skb_headroom(skb)而不是0?

[ 本帖最后由 flyfrogs 于 2008-9-10 23:13 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-09-10 23:15 |显示全部楼层
如果不是想在尾部填充数据,而是想在中间插入数据,
那么skb_copy_expand是不是就不适用了?
那用什么呢?

论坛徽章:
0
4 [报告]
发表于 2008-09-11 18:49 |显示全部楼层
我构造新的sk_buff *代码如下:
static struct sk_buff *create_skb(struct sk_buff *skb, int extra_len)
{
        int headroom;
        struct sk_buff *new_skb;

        headroom = skb_headroom(skb);
        new_skb = skb_copy_expand(skb, headroom, extra_len, GFP_ATOMIC);
        if(new_skb != NULL)
        {
                skb_put(new_skb, extra_len);
                new_skb->dev = skb->dev;
                new_skb->tstamp = skb->tstamp;
                new_skb->csum = skb->csum;
                new_skb->csum_start = skb->csum_start;
                new_skb->csum_offset = skb->csum_offset;
                new_skb->local_df = skb->local_df;
                new_skb->pkt_type = skb->pkt_type;
                new_skb->ip_summed = skb->ip_summed;
                new_skb->priority = skb->priority;
                new_skb->protocol = skb->protocol;
                new_skb->nf_bridge = skb->nf_bridge;
                new_skb->iif = skb->iif;
                new_skb->dst = skb->dst;
                new_skb->sp = skb->sp;
                MY_IPHDR(new_skb)->tot_len = htons(my_ntohs(MY_IPHDR(skb)->tot_len) + extra_len);
        }
        return new_skb;
}
然后填充TCP数据区域的数据,计算IP和TCP校验和,然后使用dev_queue_xmit发送,
但是很可惜,没发出去,我在目标机上使用commview抓包没见到这个包。

怎么回事?

论坛徽章:
0
5 [报告]
发表于 2008-09-11 19:37 |显示全部楼层
原帖由 Godbach 于 2008-9-11 19:29 发表
确定了一下skb->len = ntohs(iph->tot_len)
因此应该是主机字节序,不用转换。
                MY_IPHDR(new_skb)->tot_len = htons(my_ntohs(MY_IPHDR(skb)->tot_len) + extra_len);
这行代码修改一下, ...

被你搞晕了,我没有转换修改skb->len啊,那个宏MY_IPHDR是得到ip头指针的意思
#define MY_IPHDR(skb) ((struct iphdr *)skb->data)

论坛徽章:
0
6 [报告]
发表于 2008-09-11 20:20 |显示全部楼层
原帖由 Godbach 于 2008-9-11 19:40 发表
哈哈,那你skb->len也得修改啊,数据包长度都变了

本来有的,改来改去改没了

论坛徽章:
0
7 [报告]
发表于 2008-09-11 21:13 |显示全部楼层
试了,不是这个问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP