转贴:Linux Netlink Socket Example

  1. #include <asm/types.h>
  2. #include <sys/socket.h>
  3. #include <unistd.h>
  4. #include <err.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <linux/netlink.h>
  8. #include <linux/rtnetlink.h>
  9. #if 0
  10. //#define MYPROTO NETLINK_ARPD
  11. #define MYMGRP RTMGRP_NEIGH
  12. // if you want the above you'll find that the kernel must be compiled with CONFIG_ARPD, and
  13. // that you need MYPROTO=NETLINK_ROUTE, since the kernel arp code {re,ab}uses rtnl (NETLINK_ROUTE)
  14. #else
  15. #define MYPROTO NETLINK_ROUTE
  16. #define MYMGRP RTMGRP_IPV4_ROUTE
  17. #endif
  18. struct msgnames_t {
  19.         int id;
  20.         char *msg;
  21. } typenames[] = {
  22. #define MSG(x) { x, #x }
  23.         MSG(RTM_NEWROUTE),
  24.         MSG(RTM_DELROUTE),
  25.         MSG(RTM_GETROUTE),
  26. #undef MSG
  27.         {0,0}
  28. };
  29. char *lookup_name(struct msgnames_t *db,int id)
  30. {
  31.         static char name[512];
  32.         struct msgnames_t *msgnamesiter;
  33.         for(msgnamesiter=db;msgnamesiter->msg;++msgnamesiter) {
  34.                 if (msgnamesiter->id == id)
  35.                         break;
  36.         }
  37.         if (msgnamesiter->msg) {
  38.                 return msgnamesiter->msg;
  39.         }
  40.         snprintf(name,sizeof(name),"#%i",id);
  41.         return name;
  42. }
  43. int open_netlink()
  44. {
  45.         int sock = socket(AF_NETLINK,SOCK_RAW,MYPROTO);
  46.         struct sockaddr_nl addr;
  47.         memset((void *)&addr, 0, sizeof(addr));
  48.         if (sock<0)
  49.                 return sock;
  50.         addr.nl_family = AF_NETLINK;
  51.         addr.nl_pid = getpid();
  52.         addr.nl_groups = MYMGRP;
  53.         if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<0)
  54.                 return -1;
  55.         return sock;
  56. }
  57. int read_event(int sock)
  58. {
  59.         struct sockaddr_nl nladdr;
  60.         struct msghdr msg;
  61.         struct iovec iov[2];
  62.         struct nlmsghdr nlh;
  63.         char buffer[65536];
  64.         int ret;
  65.         iov[0].iov_base = (void *)&nlh;
  66.         iov[0].iov_len = sizeof(nlh);
  67.         iov[1].iov_base = (void *)buffer;
  68.         iov[1].iov_len = sizeof(buffer);
  69.         msg.msg_name = (void *)&(nladdr);
  70.         msg.msg_namelen = sizeof(nladdr);
  71.         msg.msg_iov = iov;
  72.         msg.msg_iovlen = sizeof(iov)/sizeof(iov[0]);
  73.         ret=recvmsg(sock, &msg, 0);
  74.         if (ret<0) {
  75.                 return ret;
  76.         }
  77.         printf("Type: %i (%s)/n",(nlh.nlmsg_type),lookup_name(typenames,nlh.nlmsg_type));
  78.         printf("Flag:");
  79. #define FLAG(x) if (nlh.nlmsg_type & x) printf(" %s",#x)
  80.         FLAG(NLM_F_REQUEST);
  81.         FLAG(NLM_F_MULTI);
  82.         FLAG(NLM_F_ACK);
  83.         FLAG(NLM_F_ECHO);
  84.         FLAG(NLM_F_REPLACE);
  85.         FLAG(NLM_F_EXCL);
  86.         FLAG(NLM_F_CREATE);
  87.         FLAG(NLM_F_APPEND);
  88. #undef FLAG
  89.         printf("/n");
  90.         printf("Seq : %i/n",nlh.nlmsg_seq);
  91.         printf("Pid : %i/n",nlh.nlmsg_pid);
  92.         printf("/n");
  93.         return 0;
  94. }
  95. int main(int argc, char *argv[])
  96. {         int nls = open_netlink();
  97.         if (nls<0) {
  98.                 err(1,"netlink");
  99.         }
  100.         while (1)
  101.                 read_event(nls);
  102.         return 0;
  103. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值