首页 > 解决方案 > 卡在 netlink、connektor、socket 和 co 上

问题描述

我对 netlink & co 完全陌生。我正在尝试建立从用户空间到树莓派的 w1-kernel 模块的连接。不幸的是,我发现的文档参差不齐且相互矛盾。

这里有些事情我不清楚:

基本沟通是:

    sa.nl_family=AF_NETLINK;
    sa.nl_pid=getpid();//0?
    sa.nl_groups=0; //23? -1?

+在我发现的示例(w1d.c 和 ucon.c)中,他们使用send()没有 connect() 的命令(不是 sendmsg),即使 send 的手册页说这不起作用。

+我不清楚消息的结构:

我需要连续的所有标题吗?有 2 个序列/消息编号变量,一个在 nlmsghdr 中,一个在 cn_msg 中???

我编写的测试程序没有产生我期望的结果:每件事都能产生错误,但我没有得到答案:-(

#include <iostream>
#include <linux/netlink.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<sys/poll.h>
#include <unistd.h>
#include<cstring>
#include "w1_netlink.h"

__u32 nl_seq;


static int netlink_send(int s, struct cn_msg *msg) //copy from (ucon.c)
{
    struct nlmsghdr *nlh;
    unsigned int size;
    int err;
    char buf[128];
    struct cn_msg *m;

    size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);

    nlh = (struct nlmsghdr *)buf;
    nlh->nlmsg_seq = nl_seq++;
    nlh->nlmsg_pid = getpid();
    nlh->nlmsg_type = NLMSG_DONE;
    nlh->nlmsg_len = size;
    nlh->nlmsg_flags = 0;

    m = (cn_msg*) NLMSG_DATA(nlh);
    memcpy(m, msg, sizeof(*m) + msg->len);

    err = send(s, nlh, size, 0);

    return err;
}

int main(int argc, char *argv[])
{
    nl_seq=0;
    int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
    if(s==-1) {std::cout<<"no socket"; return s;};
    std::cout<<"socket "<<s;

    sockaddr_nl sa;
    sa.nl_family=AF_NETLINK;
    sa.nl_pid=0;//getpid();
    sa.nl_groups=0;

    int b = bind(s,(sockaddr*)&sa,sizeof(sa));
    if(b==-1){std::cout<<"bind error";return b;};    //prints 3
    std::cout<<"bind "<<b;    //prints 0
    int si=sizeof(struct cn_msg)+sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);

    char * buf;
    buf=(char *)malloc(1024);
    memset(buf,0,1024);
    cn_msg *cnh = (cn_msg*)buf;
    w1_netlink_msg* wnh=(w1_netlink_msg*)&cnh->data;
    w1_netlink_cmd* wcmd = (w1_netlink_cmd*)&wnh->data;  

    cnh->id.idx=CN_W1_IDX;
    cnh->id.val=CN_W1_VAL;
    cnh->seq=nl_seq;
    cnh->flags=0;

    wnh->type=W1_LIST_MASTERS;
    wnh->len=0;
    cnh->len=sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);


    int len=netlink_send(s,cnh);
    std::cout<<"send "<<len<<" "<<(int)wnh->status;   //prints 52  0
    pollfd pfd;
    pfd.fd=s;
    pfd.events=POLLIN;
    pfd.revents=0;
    int p=0;
    while(p<1) {
        p=poll(&pfd,1,1000);
        std::cout<<"poll "<<p<<pfd.revents;   //prints 0 0  in infinite loop
        std::cout.flush();
    };
    memset(wcmd,0,128);
    len=recv(s,buf,255,0);
    std::cout<<"recv "<<len;
    close(s);
    return 0;
}

结果是socket 3 bind 0 send 52 0 poll 00 poll 00 ...

谢谢

标签: socketskernelconnectornetlink

解决方案


推荐阅读