免费注册 查看新帖 |

Chinaunix

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

[内核模块] netlink套接字:recvmsg收到内核信息为乱码?? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-29 21:04 |只看该作者 |倒序浏览
参考了网站:http://edsionte.com/techblog/archives/4134
  Netlink编程-用户主动发起会话
我在linux中运行了一变,但是不知道为什么 在最后的输出的时候:
printf("Received message payload:%s\n", (char *)NLMSG_DATA(&r.nlh));
输出的是一个乱码!
这是为什么 求大神帮忙一下 谢谢
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <asm/types.h>
  9. #include <sys/socket.h>
  10. #include <linux/netlink.h>
  11. #include <linux/inet_diag.h>
  12. #include <netinet/tcp.h>

  13. #define NETLINK_TEST 18
  14. #define MAX_PAYLOAD 1024
  15. struct req {
  16.         struct nlmsghdr nlh;
  17.         char buf[MAX_PAYLOAD];
  18. };

  19. void eprint(int err_no, char *str, int line)
  20. {
  21.         printf("Error %d in line %d:%s() with %s\n", err_no, line, str, strerror(errno));
  22. }
  23. int main()
  24. {
  25. int sock_fd;
  26. sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
  27. if (sock_fd < 0) {
  28.         eprint(errno, "socket", __LINE__);
  29.     return errno;
  30. }
  31. //将本地套接字与源地址绑定
  32. struct sockaddr_nl src_addr;
  33. memset(&src_addr, 0, sizeof(src_addr));
  34. src_addr.nl_family = AF_NETLINK;
  35. src_addr.nl_pid = getpid();                 //nl_pid字段指明发送消息一方的pid
  36. src_addr.nl_groups = 0;                                                //nl_groups表示多播组的掩码  这里我们并没有涉及多播,因此默认为0

  37. if (bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
  38.         eprint(errno, "bind", __LINE__);
  39.         return errno;
  40. }


  41. /*
  42. struct msghdr {
  43.         void        *        msg_name;        // Socket name                        
  44.         int                msg_namelen;        //Length of name               
  45.         struct iovec *        msg_iov;        // Data blocks                        
  46.         __kernel_size_t        msg_iovlen;        // Number of blocks               
  47.         void         *        msg_control;        // Per protocol magic (eg BSD file descriptor passing)
  48.         __kernel_size_t        msg_controllen;        // Length of cmsg list
  49.         unsigned        msg_flags;
  50. };*/
  51. /*
  52. struct sockaddr_nl {
  53.         __kernel_sa_family_t        nl_family;        // AF_NETLINK        
  54.         unsigned short        nl_pad;                //zero               
  55.         __u32                nl_pid;                // port ID        
  56.                __u32                nl_groups;        // multicast groups mask
  57. };*/

  58. struct sockaddr_nl dest_addr;
  59. memset(&dest_addr, 0, sizeof(dest_addr));
  60. dest_addr.nl_family = AF_NETLINK;
  61. dest_addr.nl_pid = 0;   //即nl_pid必须为0,表示接收方为内核。                 
  62. dest_addr.nl_groups = 0;                 
  63. //req类型的数据报进行初始化,即依次对其封装的两个数据结构初始化:

  64. struct req r;//自定义协议数据结构  使用netlink进行用户进程和内核的数据交互时 用到
  65. r.nlh.nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);                                /*这里的nlmsg_len为为sizeof(structnlmsghdr)+MAX_PAYLOAD的总和。宏NLMSG_SPACE会自动将两者的长度相加
  66. #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
  67. #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) */

  68. r.nlh.nlmsg_pid = getpid();
  69. r.nlh.nlmsg_flags = 0;
  70. memset(r.buf, 0, MAX_PAYLOAD);
  71. strcpy(NLMSG_DATA(&(r.nlh)), "hello, I am edsionte!");        //#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))

  72. //接下来对缓冲区向量iov进行初始化,让iov_base字段指向数据报结构,而iov_len为数据报长度。
  73. struct iovec iov;
  74. iov.iov_base = (void *)&r;
  75. iov.iov_len = sizeof(r);

  76. struct msghdr msg;
  77. msg.msg_name = (void *)&dest_addr;
  78. msg.msg_namelen = sizeof(dest_addr);
  79. msg.msg_iov = &iov;
  80. msg.msg_iovlen = 1;

  81. //.向内核发送消息
  82. if (sendmsg(sock_fd, &msg, 0) < 0) {
  83.     eprint(errno, "sendmsg", __LINE__);
  84.     return errno;
  85. }

  86. //接收内核发来的消息
  87. memset(&r.nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
  88. if (recvmsg(sock_fd, &msg, 0) < 0) {
  89.         eprint(errno, "recvmsg", __LINE__);
  90.         return errno;
  91. }
  92. printf("Received message payload:%s\n", (char *)NLMSG_DATA(&r.nlh));
  93. close(sock_fd);
  94. }








复制代码

论坛徽章:
3
午马
日期:2013-09-09 21:55:38天秤座
日期:2014-03-04 10:39:14午马
日期:2014-05-05 18:56:36
2 [报告]
发表于 2014-05-30 14:20 |只看该作者
我运行了一下你的代码,Error 105 in line 94:sendmsg() with No buffer space available
这是结果

论坛徽章:
0
3 [报告]
发表于 2014-05-30 19:14 |只看该作者
回复 2# 我不重要


  您好 ,谢谢你 的回复 ,请问你是怎么运行的,我运行之后是没有错误的我的环境是在ubuutn12.04中  gcc net.c -o net 运行之后没有错误

gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
目标:i686-linux-gnu
配置为:../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
线程模型:posix
gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

论坛徽章:
3
午马
日期:2013-09-09 21:55:38天秤座
日期:2014-03-04 10:39:14午马
日期:2014-05-05 18:56:36
4 [报告]
发表于 2014-05-31 17:41 |只看该作者
回复 3# SCDXMOE


使用内建 specs。
目标:i686-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
线程模型:posix
gcc 版本 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)

论坛徽章:
3
午马
日期:2013-09-09 21:55:38天秤座
日期:2014-03-04 10:39:14午马
日期:2014-05-05 18:56:36
5 [报告]
发表于 2014-05-31 17:42 |只看该作者
回复 3# SCDXMOE

[root@localhost ~]# ./a.out
Error 14 in line 94:sendmsg() with Bad address
[root@localhost ~]# cc -v
使用内建 specs。
目标:i686-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
线程模型:posix
gcc 版本 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP