免费注册 查看新帖 |

Chinaunix

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

[内核模块] 我用netfilter在NF_ARP_IN注册hook函数,并用netlink接受数据问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-07 17:00 |只看该作者 |倒序浏览
本帖最后由 d4flash 于 2014-08-08 11:43 编辑

我的linux内核版本是2.6.32.62
首先我NF_ARP_IN注册了hook函数ParsePacket
        stHookOps.hook = ParsePacket;
        stHookOps.hooknum = NF_ARP_IN;
        stHookOps.pf = NF_ARP;
        stHookOps.priority = NF_IP_PRI_FILTER;

        int err = nf_register_hook(&stHookOps);

ParsePacket原型如下:
unsigned int ParsePacket(unsigned int hooknum, struct sk_buff *skb, const struct net_device *indev, const struct net_device *outdev, int(*okfn)(struct sk_buff *))
{
    if(skb == NULL || user_process.pid ==0 || pNetlinkFD == NULL)
    {
        return ;
    }

        int nArpLen = arp_hdr_len(skb->dev);
        struct sk_buff *pNetlinkSKB = alloc_skb(NLMSG_SPACE(nArpLen), GFP_ATOMIC);
    if (pNetlinkSKB == NULL)
    {
        return;
    }

        struct nlmsghdr *pNetlinkHeader = nlmsg_put(pNetlinkSKB, 0, 0, 0, NLMSG_SPACE(nArpLen) - sizeof(struct nlmsghdr), 0);
        memcpy(NLMSG_DATA(pNetlinkHeader), (unsigned char *)(arp_hdr(skb)), nArpLen);
       
   netlink_unicast(pNetlinkFD, pNetlinkSKB, user_process.pid, MSG_DONTWAIT);
   
   return NF_DROP;
}

然后创建了一个netlink
#defined NETLINK_ARP 17

pNetlinkFD = netlink_kernel_create(&init_net, NETLINK_ARP, 0, ReceiveFromUser, NULL, THIS_MODULE);

void ReceiveFromUser(struct sk_buff *skb)
{
    struct nlmsghdr *pNetlinkHeader = NULL;
    if(skb->len >= sizeof(struct nlmsghdr)){
        pNetlinkHeader = (struct nlmsghdr *)skb->data;
        if((pNetlinkHeader->nlmsg_len >= sizeof(struct nlmsghdr)) && (skb->len >= pNetlinkHeader->nlmsg_len))        {
            user_process.pid = pNetlinkHeader->nlmsg_pid;
        }
    }
}


以上是模块代码,,,
模块加载进去后,我就按照netlink的流程,做
    nSocketFd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ARP );
    int nRet = bind(nSocketFd, (struct sockaddr*)&stLocalAddress), sizeof(stLocalAddress));

   struct REQUEST_TO_KENEL
    {
                struct nlmsghdr stNetLinkMsgHeader;
                ipq_peer_msg_t stIPQueueMsgBody;
};

    struct REQUEST_TO_KENEL stRequestToKernel;
    memset(&stRequestToKernel, 0, sizeof(stRequestToKernel));
    stRequestToKernel.stNetLinkMsgHeader.nlmsg_len = NLMSG_LENGTH(sizeof(stRequestToKernel));
    stRequestToKernel.stNetLinkMsgHeader.nlmsg_flags = NLM_F_REQUEST;
    stRequestToKernel.stNetLinkMsgHeader.nlmsg_type = IPQM_MODE;
    stRequestToKernel.stNetLinkMsgHeader.nlmsg_pid = stLocalAddress.nl_pid;
    stRequestToKernel.stIPQueueMsgBody.msg.mode.value = IPQ_COPY_PACKET;
    stRequestToKernel.stIPQueueMsgBody.msg.mode.range = 1024 * 2;

    nRet = sendto(nSocketFd, (void*)&stRequestToKernel, stRequestToKernel.stNetLinkMsgHeader.nlmsg_len, 0, (struct sockaddr *)&stPeerAddress, sizeof(stPeerAddress));


做完这些后,我就用recvfrom去接受数据。。


上述整个过程感觉是没有问题的,,但是我通过recvfrom接收不到任何数据,,为啥呢???
我另外一个进程是netlink去接受NETLINK_FIREWALL的数据,是正常的,实现和这个也差不多,唯一不同的是NETLINK_ARP 是我自己注册的协议。
另外,内核中是不是需要做一些配置来支持自定义协议功能?或者我有些什么和ARP相关的模块没有编译进去?
请大家帮助下我,,谢谢。。

20140808追加:
我还是觉得内核里应该需要配置些支持arp包截取的设置,,,我现在是把以下三个编译进内核了,

但好像不行。。。

论坛徽章:
0
2 [报告]
发表于 2014-08-07 18:23 |只看该作者
   int nRet = bind(nSocketFd, (struct sockaddr*)&stLocalAddress), sizeof(stLocalAddress));。。。是不是&stLocalAddress多了一个)。。

论坛徽章:
0
3 [报告]
发表于 2014-08-07 19:10 |只看该作者
不啊 ,前一个是地址,后一天是size啊回复 2# 黎明748


   

论坛徽章:
0
4 [报告]
发表于 2014-08-07 20:49 |只看该作者
本帖最后由 黎明748 于 2014-08-07 20:50 编辑

你这句话是写错了呢,你看清楚点回复 3# d4flash


   

论坛徽章:
0
5 [报告]
发表于 2014-08-07 20:57 |只看该作者
对,,,您说的这个确实是,,不过,问题肯定不在那的,,那个笔误,,要不根本编译不过的,,回复 4# 黎明748


   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
6 [报告]
发表于 2014-08-08 12:58 |只看该作者
回复 1# d4flash

netlink_unicast 的返回值打印一下看看是否成功了


   

论坛徽章:
0
7 [报告]
发表于 2014-08-08 13:49 |只看该作者
本帖最后由 d4flash 于 2014-08-08 13:59 编辑

还根本跑不到那里去,,注册的这个kook函数ParsePacket根本就没有进去,
但我用netlink_kernel_create注册的这个ReceiveFromUser,可以收到应用程序的pid等。。

所以我觉得是nf_register_hook(&stHookOps);这个地方会不会有问题?,或者内核中忘记配置什么?

还有了,,我测试这个驱动的时候就是用ping命令去测试,ping命令开始会发一个arp包,请求谁是ping的地址。这样测试,应该没问题。。

感觉没有hook上,需要内核配置哪些东西,才能勾取到MAC层的数据包?


另外  我ping的时候 网卡驱动打了一个系统日志(后两行),,这个是什么意思?有影响吗?(前三行是内核模块收到应用程序的包的打印信息)


回复 6# Godbach


   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2014-08-08 14:11 |只看该作者
回复 7# d4flash

你指的是 报文根本没有进入到你注册的 Hook 里面吧
   

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
9 [报告]
发表于 2014-08-08 14:16 |只看该作者
回复 7# d4flash

可以先简单试试 arp table 是否好用。

然后你看一下 arptable_filter_init 这个函数是怎么注册 hook 的。

   

论坛徽章:
0
10 [报告]
发表于 2014-08-08 15:22 |只看该作者
本帖最后由 d4flash 于 2014-08-08 15:23 编辑

我找到原因了,还是自己对内核模块编程的理解不够深入,
linux内核的接口是不稳定,linux那些维护者可在不通知使用者的情况下,对内核的接口进行修改。所以,内核模块编程一定到对应好自己需要选用的内核版本。(引自godbach)

我这块内核模块的编程修改源于godbach的一篇文章里的描写。

他之前的内核版本应该比我现在用的要低,include/linux/netfilter_arp.h这个文件的内容如下:

但到了我使用的内核,2.6.32.62的内核中,netfilter_arp.h这个文件发生了很大的变化,去掉了NF_ARP的定义


所以我将1楼代码中的
stHookOps.pf = NF_ARP;
修改成
stHookOps.pf = NFPROTO_ARP;

就能正常接受到arp数据了。

对我算是个教训吧,,搞了将近3天,搞的头都大了,谁想到是这么一个小的原因。

借此贴也提醒下CU论坛里的其他开发者们。内核模块一定要和内核版本对应的编程啊。。。。。

谢谢大家了,,结贴。
回复 9# Godbach


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP