+ -
当前位置:首页 → 问答吧 → 公司的防火墙源代码.一个注册proc文件的读函数看不懂

公司的防火墙源代码.一个注册proc文件的读函数看不懂

时间:2011-07-21

来源:互联网

C/C++ code
static ssize_t read_ipmac_bind(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
{
    int len = 0, i;
    char ip[16];

    off_t pos = 0, begin = 0;
    struct ipmac_item *bp;

    len += sprintf(buffer + len, "%-16s%-20s\n", "IPAddr", "MAC");

    if ((i = get_index()) == -1)
        goto done_version_i;

    for (; i < BASE_SIZE; i++) {
        if (ipmac_base[i]) {
            for (bp = ipmac_base[i]; bp; bp = bp->next) {
                sprintf(ip, "%u.%u.%u.%u", ntohl(bp->ip) >> 24 & 0xff, ntohl(bp->ip) >> 16 & 0xff, ntohl(bp->ip) >> 8 & 0xff, ntohl(bp->ip) & 0xff);
                len += sprintf(buffer + len, "%s\t%02x:%02x:%02x:%02x:%02x:%02x\n", ip, bp->mac[0], bp->mac[1], bp->mac[2], bp->mac[3], bp->mac[4], bp->mac[5]);
                pos = begin + len;
                if (pos < offset) {
                    len = 0;
                    begin = pos;
                } else if (pos > offset + length) {
                    goto done_version_i;
                }
            }
        }
    }

      done_version_i:
    *start = buffer + (offset - begin);    /* Start of wanted data */
    len -= (offset - begin);    /* Start slop */
    if (len > length)
        len = length;
    return len;
}

作者: kuikuiwoaini   发布时间: 2011-07-21

C/C++ code
 pos = begin + len;
                if (pos < offset) {
                    len = 0;
                    begin = pos;
                } else if (pos > offset + length) {
                    goto done_version_i;
                }
            }
        }
    }

      done_version_i:
    *start = buffer + (offset - begin);    /* Start of wanted data */
    len -= (offset - begin);    /* Start slop */




问题就在这里.他到底想干嘛?实现的什么逻辑?
我对参数的理解.start只是一个逻辑的值对函数没有意思.
每次offset参数的跟新 = 老的offset+传上去的start.  

函数会不停·地读每次最多只能读length这么多数据.
内核会不停地调用这个读函数直到全部读完为止.


请高手解释下这段代码的逻辑实现了什么功能

作者: kuikuiwoaini   发布时间: 2011-07-21

我刚从学校出来的人,既要我把安全网关从linux2.4内核网2.6.22内核上面移植...哎真是悲剧求高手帮忙

作者: kuikuiwoaini   发布时间: 2011-07-21

这个代码很容易理解啊,不过有个bug,如果调用者传入比较小的缓存进来 length < 36时,系统会挂掉。 sprintf 前都不做检查的。

.start 明显告诉调用者,真正的数据从那里开始。

用户传过来的内存快

  | <--- length ----> |
  ^
offset 

这个函数里面,就是看看 begin 和pos这个是不是落在offset 和length的区域里面,是就填到buffer里面就可以了。

-------------|---------|------------
  ^ ^
  begin pos

   

作者: lvyinghong   发布时间: 2011-07-21

HTML code

<pre>
-------------|---------|------------
             ^         ^
             begin     pos

i++  --------->>>>>>>>>>

</pre>

作者: lvyinghong   发布时间: 2011-07-21

楼上朋友再详细点好不...我新手啊...
主要的问题是offset每次如何更新的问题.

它是等于老的offset+传上去的start对吧?
*start = buffer + (offset - begin);  

buff是分配的内存区的起始地址对吧.
第二次调用这个读函数的时候offset= 0(第一次调用的offset值) + *start
我这样理解对吗?

作者: kuikuiwoaini   发布时间: 2011-07-21

那第二次调用这个函数的时候.offset的值不是等于内存空间的起始地址了吗?offset只是一个偏移量的值啊.

作者: kuikuiwoaini   发布时间: 2011-07-21

可能我对这个函数的机制还是不太了解.能麻烦楼上的朋友,通过第一次调用这个函数和第二次调用这个函数,各个参数如何变化传递讲讲吗?
麻烦了啊

作者: kuikuiwoaini   发布时间: 2011-07-21

热门下载

更多