免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1251 | 回复: 0
打印 上一主题 下一主题

关于linux下的skb_replace [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-30 09:53 |只看该作者 |倒序浏览
在linux2.0.X下skb_replace实现如下,linux2.2X下也是类似实现:

static struct sk_buff * skb_replace(struct sk_buff *skb, int pri, char *o_buf, int o_len, char *n_buf, int n_len)
{
        int maxsize, diff, o_offset;
        struct sk_buff *n_skb;
        int offset;

        maxsize = skb->truesize;

        diff = n_len - o_len;
        o_offset = o_buf - (char*) skb->data;
       /*
        *此处很不明白,maxsize应该是之前skb实际buffer的程度,n_len是新的buffer的长度,
        *如下的这种做法是不是反了?
        */

        if (maxsize <= n_len) {
            if (diff != 0) {
                memcpy(skb->data + o_offset + n_len,o_buf + o_len,
                       skb->len - (o_offset + o_len));
            }

            memcpy(skb->data + o_offset, n_buf, n_len);

            n_skb    = skb;
            skb->len = n_len;
            skb->end = skb->head+n_len;
        } else {
                /*
                 *      Sizes differ, make a copy.
                 *
                 *      FIXME: move this to core/sbuff.c:skb_grow()
                 */

                n_skb = alloc_skb(MAX_HEADER + skb->len + diff, pri);
                if (n_skb == NULL) {
                        IP_MASQ_ERR("skb_replace(): no room left (from %p)\n",
                               __builtin_return_address(0));
                        return skb;

                }
                skb_reserve(n_skb, MAX_HEADER);
                skb_put(n_skb, skb->len + diff);

                /*
                 *      Copy as much data from the old skb as possible. Even
                 *      though we're only forwarding packets, we need stuff
                 *      like skb->protocol (PPP driver wants it).
                 */
                offset = n_skb->data - skb->data;
                n_skb->nh.raw = skb->nh.raw + offset;
                n_skb->h.raw = skb->h.raw + offset;
                n_skb->dev = skb->dev;
                n_skb->mac.raw = skb->mac.raw + offset;
                n_skb->pkt_type = skb->pkt_type;
                n_skb->protocol = skb->protocol;
                n_skb->ip_summed = skb->ip_summed;
                n_skb->dst = dst_clone(skb->dst);

                /*
                 * Copy pkt in new buffer
                 */

                memcpy(n_skb->data, skb->data, o_offset);
                memcpy(n_skb->data + o_offset, n_buf, n_len);
                memcpy(n_skb->data + o_offset + n_len, o_buf + o_len,
                       skb->len - (o_offset + o_len) );

                /*
                 * Problem, how to replace the new skb with old one,
                 * preferably inplace
                 */

                kfree_skb(skb);
        }
        return n_skb;
}

[ 本帖最后由 fangshi168775 于 2009-3-30 09:58 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP