免费注册 查看新帖 |

Chinaunix

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

[Linux] 通过netlink获取套接字状态 程序出错 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-16 10:04 |只看该作者 |倒序浏览
各位好,我想通过netlink的NETLINK_INET_DIAG协议获取指定套接字的链接状态,但是每次执行的时候都会有下面的错误:

edsionte@edsionte-VirtualBox ~/netlink $ ./a.out
enter while1..
89 Error 116:Stale NFS file handle

不知道这是怎么回事?
程序如下:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <asm/types.h> //NLMSG_OK()
#include <sys/socket.h> //
#include <linux/netlink.h>
#include <linux/inet_diag.h>

int main(int argc, char **argv)
{
        int fd;
        struct sockaddr_nl nladdr;
        struct {
                struct nlmsghdr nlh;
                struct inet_diag_req r;
        } req;
        struct inet_diag_msg *pkg;
        struct msghdr msg;
        char buf[8192];
        struct iovec iov;

        if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG)) < 0)
                return -1;

        memset(&nladdr, 0, sizeof(nladdr));
        nladdr.nl_family = AF_NETLINK;
        nladdr.nl_pid = 0;
        nladdr.nl_groups = 0;

        if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
                fprintf(stderr, "bind socket error %s\n", strerror(errno));
        }

        memset(&req, 0, sizeof(req));
        req.nlh.nlmsg_len = sizeof(req);
        req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
        req.nlh.nlmsg_flags = NLM_F_REQUEST;
        req.nlh.nlmsg_pid = getpid();
        //req.nlh.nlmsg_seq = 123456;
        memset(&req.r, 0, sizeof(req.r));
        req.r.idiag_family = AF_INET;
        //req.r.idiag_states = 0; //states to dump
        req.r.id.idiag_sport = htons(53);
        req.r.id.idiag_dport = htons(0);
        inet_pton(AF_INET, "127.0.0.1", req.r.id.idiag_src);
        inet_pton(AF_INET, "0.0.0.0", req.r.id.idiag_dst);
       

        //send msg to kernel
        iov.iov_base = &req;
        iov.iov_len = sizeof(req);

        msg.msg_name = (void *)&nladdr;
        msg.msg_namelen = sizeof(nladdr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;

        if (sendmsg(fd, &msg, 0) < 0)
                return -1;
/*
        //recv msg from kernel
        iov.iov_base = buf;
        iov.iov_len = sizeof(buf);
*/       
        printf("enter while1..\n");
        while (1) {
                int status;
                struct nlmsghdr *h;
/*
                msg = (struct msghdr) {
                        (void *)&nladdr, sizeof(nladdr),
                                &iov, 1, NULL, 0, 0
                };
*/
//                status = recvmsg(fd, &msg, 0);
                status = recv(fd, buf, sizeof(buf), 0);               
                if (status < 0)
                        break;
                h = (struct nlmsghdr *)buf;
               
                while (NLMSG_OK(h, status)) {
                        if (h->nlmsg_type == NLMSG_DONE)
                                break;
                        if (h->nlmsg_type == NLMSG_ERROR) {
                                struct nlmsgerr *err;
                                err = (struct nlmsgerr*)NLMSG_DATA(h);
                                fprintf(stderr, "%d Error %d:%s\n", __LINE__, -(err->error), strerror(-(err->error)));
                                break;
                        }

                        pkg = (struct inet_diag_msg *)NLMSG_DATA(h);
                        fprintf(stderr, "Get a PKG:\n");
                        fprintf(stderr, "Family:%s", pkg->idiag_family == AF_INET ? "AF_INET" : "AF_INET6");
                }//while
                h = NLMSG_NEXT(h, status);
                /*
                if (status < 0) {
                        if (errno == EINTR)
                                continue;
                        perror("OVERRUN");
                        continue;
                }

                if (status == 0) {
                        fprintf(stderr, "EOF on netlink\n");
                        close(fd);
                        return 0;
                }

                printf("fwrite..\n");
//                fwrite(buf, 1, NLMSG_ALIGN(status), stdout);

                h = (struct nlmsghdr *)buf;

                while (NLMSG_OK(h, status)) {
                        int err;
                        struct inet_diag_msg *r = NLMSG_DATA(h);

                        if (h->nlmsg_seq != 123456)
                                goto skip_it;

                        if (h->nlmsg_type == NLMSG_DONE) {
                                close(fd);
                                return 0;
                        }

                        if (h->nlmsg_type == NLMSG_ERROR) {
                                struct nlmsger *err = (struct nlmsgerr *)NLMSG_DATA(h);
                                if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
                                        fprintf(stderr, "ERROR truncated\n");
                                } else {
                //                        errno = -err->error;
                                        perror("TCPDIAG answers");
                                }

                                close (fd);
                                return 0;
                        }
skip_it:
                        h = NLMSG_NEXT(h, status);
                }//while
                if (msg.msg_flags & MSG_TRUNC) {
                        fprintf(stderr, "Message truncated\n");
                        continue;
                }

                if (status) {
                        fprintf(stderr," !!Remnant of size %d\n", status);
                        exit(1);
                }
                */
        }//while
        close(fd);
        return 0;
}

论坛徽章:
0
2 [报告]
发表于 2012-08-16 10:24 |只看该作者
已经解决:

添加两句话:


        req.r.id.idiag_cookie[0] = INET_DIAG_NOCOOKIE;
        req.r.id.idiag_cookie[1] = INET_DIAG_NOCOOKIE;


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP