免费注册 查看新帖 |

Chinaunix

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

[内核入门] netlink导致死机 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-12 10:56 |只看该作者 |倒序浏览
加载后,向内核发送据之后,就死机了,请高手指点
内核版本:2.6.32-21-generic
内核源码
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/proc_fs.h>

#define BUF_SIZE 16384
static struct sock *netlink_exam_sock;
static unsigned char buffer[BUF_SIZE];
static unsigned int buffer_tail = 0;

static void recv_handler(struct sk_buff *__skb)
{
        struct nlmsghdr * nlhdr = NULL;
        int len;
        struct sk_buff *skb;
        
        skb = __skb;
        /* êÕμ½êy¾Yoó£¬ò»·YÔY′æ»o3壬ò»·Y¶à2¥3öè¥ */
        if (!skb)
        {
            return;
        }
        nlhdr = (struct nlmsghdr *)skb->data;
        if (!nlhdr)
        {
            return;
        }
        len = nlhdr->nlmsg_len - NLMSG_LENGTH(0);
        if (len < 0)
        {
            printk(KERN_ERR "netlink recv error.\n");
            return;
        }
        else
        {
            printk(KERN_ERR "netlink recv %d.\n", len);
        }
        /* »o3åÇøoľ¡£¬·Ç»·DÎμÄ£¬Ö»êÇÔúÄú′æÔY′æó|óÃ2ãêy¾Y */
        if (len + buffer_tail > BUF_SIZE) {
                printk(KERN_ERR "netlink buffer is full.\n");
        }
        else {
               
                memcpy(buffer + buffer_tail, NLMSG_DATA(nlhdr), len);
                buffer_tail += len;
        }
        /* Ôú¶à2¥×é1ÖD1ã2¥±¾′νóêÕêy¾Y */
        nlhdr->nlmsg_pid = 0;
        nlhdr->nlmsg_flags = 0;
        NETLINK_CB(skb).pid = 0;
        /* ½óêÕ½ø3ì¼óèë×é2¥×é1ÖD ËùòÔÕaàïéèÖÃÎa1 */
        NETLINK_CB(skb).dst_group = 1;
        netlink_broadcast(netlink_exam_sock, skb, 0, 1, GFP_KERNEL);
      

}



/* cat ¶¼êÇòÔò3Îaμ¥λ½øDD¶áμÄ D′μľí2»è·¶¨áË */
static int netlink_exam_readproc(char *page, char **start, off_t off,
                          int count, int *eof, void *data)
{
        int len;

        if (off >= buffer_tail) {
                * eof = 1;
                return 0;
        }
        else {
                len = count;
                if (count > PAGE_SIZE) {
                        len = PAGE_SIZE;
                }
                if (len > buffer_tail - off) {
                        len = buffer_tail - off;
                }
                memcpy(page, buffer + off, len);
                *start = page;
                return len;
        }

}

static int __init netlink_exam_init(void)
{
        /* ½ó¿úÔú>=kernel 2.6.24±ä»ˉoó£¬Ã»·¨óöàÏß3ì′|àíáË£¬¿éòÔ¶Ô±èÑ1Ëõ°üÖD′úÂë */
        netlink_exam_sock = netlink_kernel_create(&init_net, NETLINK_HELUN, 1, recv_handler, NULL,THIS_MODULE);
        /* ·μ»Ø3ö′í′ó¶àêyòòÎaD-òéoű»Õ¼óã¬ÄúoËí·Îļt£¬¿aí·Îļt¶¼òaDT¸Ä(ó|óÃ3ìDòê1óà NETLINK_HELUN) */
        if (!netlink_exam_sock) {
                printk("Fail to create netlink socket.\n");
                return 1;
        }

        /* ′′½¨ÎļtÏμí3½áμ㣬¶á2ù×÷ */
        create_proc_read_entry("netlink_exam_buffer", 0444, NULL, netlink_exam_readproc, 0);
        return 0;
}

static void __exit netlink_exam_exit(void)
{
        if (netlink_exam_sock)
        {
            wake_up(netlink_exam_sock->sk_sleep);
            sock_release(netlink_exam_sock->sk_socket);
        }
}

module_init(netlink_exam_init);
module_exit(netlink_exam_exit);
MODULE_LICENSE("GPL");

send进程源码

#define MAX_MSGSIZE 1024


int main(int argc, char * argv[])
{
        FILE * fp;
        struct sockaddr_nl saddr, daddr;
        struct nlmsghdr *nlhdr = NULL;
        struct msghdr msg;
        struct iovec iov;
        int sd;
        unsigned int count = 0;
        char text_line[MAX_MSGSIZE];
        int ret = -1;

        if (argc < 2) {
                printf("Usage: %s atextfilename\n", argv[0]);
                exit(1);
        }

        if ((fp = fopen(argv[1], "r")) == NULL) {
                printf("File %s dosen't exist.\n");
                exit(1);
        }

        sd = socket(AF_NETLINK, SOCK_RAW,NETLINK_HELUN);
        memset(&saddr, 0, sizeof(saddr));
        memset(&daddr, 0, sizeof(daddr));

        saddr.nl_family = AF_NETLINK;      
        saddr.nl_pid = getpid();
        saddr.nl_groups = 0;
        bind(sd, (struct sockaddr*)&saddr, sizeof(saddr));

        daddr.nl_family = AF_NETLINK;
        daddr.nl_pid = 0;
        daddr.nl_groups = 0;

        nlhdr = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSGSIZE));

        while (fgets(text_line, MAX_MSGSIZE, fp)) {
                memcpy(NLMSG_DATA(nlhdr), text_line, strlen(text_line));
                printf("%d:%s\n", count++, text_line);
                memset(&msg, 0 ,sizeof(struct msghdr));

                nlhdr->nlmsg_len = NLMSG_LENGTH(strlen(text_line));
                nlhdr->nlmsg_pid = getpid();  /* self pid */
                nlhdr->nlmsg_flags = 0;

                iov.iov_base = (void *)nlhdr;
                iov.iov_len = nlhdr->nlmsg_len;
                msg.msg_name = (void *)&daddr;
                msg.msg_namelen = sizeof(daddr);
                msg.msg_iov = &iov;
                msg.msg_iovlen = 1;
                ret = sendmsg(sd, &msg, 0);
                if (ret == -1) {
                        perror("sendmsg error:");
                } else
                {
                        printf("send %d \n", ret);
                }
        }

        close(sd);
}

论坛徽章:
0
2 [报告]
发表于 2013-12-16 14:44 |只看该作者
原因找到了skb,需要别外申请一块 。传入的是由内核管理的 ,什么时候释放我们不知道,很可能是释放了 应用层引用 导致死机了。再COPY一块就没问题了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP