Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66049
  • 博文数量: 11
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 120
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-06 15:04
文章分类
文章存档

2018年(11)

我的朋友

分类: LINUX

2018-04-20 22:15:17

通过netlink监控arp实时变更


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <signal.h>
  6. #include <errno.h>
  7. #include <sys/types.h>
  8. #include <asm/types.h>
  9. #include <arpa/inet.h>
  10. #include <sys/socket.h>
  11. #include <linux/netlink.h>
  12. #include <linux/rtnetlink.h>
  13. #include <linux/route.h>
  14. #include <sys/stat.h>
  15. #include <dirent.h>
  16. #include <sys/ioctl.h>
  17. #include <netinet/in.h>
  18. #include <libconfig.h>

  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <unistd.h>
  22. #include <syslog.h>
  23. #include <fcntl.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/socket.h>
  26. #include <sys/ioctl.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <string.h>

  30. #include <linux/netdevice.h>
  31. #include <linux/if_arp.h>
  32. #include <linux/sockios.h>

  33. #define BIT_IP(x)    ((unsigned char*)&(x))
  34. #define STR_IP(x)    BIT_IP(x)[0], BIT_IP(x)[1], BIT_IP(x)[2], BIT_IP(x)[3]
  35. #define STR_IPH(x)    BIT_IP(x)[3], BIT_IP(x)[2], BIT_IP(x)[1], BIT_IP(x)[0]
  36. #define FMT_IP        "%d.%d.%d.%d"

  37. #ifndef NDA_RTA
  38. #define NDA_RTA(r) \
  39.     ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
  40. #endif
  41. #ifndef NDA_PAYLOAD
  42. #define NDA_PAYLOAD(n)    NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
  43. #endif

  44. void arp_parse_rattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
  45. {
  46.     memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
  47.     while (RTA_OK(rta, len)) {
  48.         if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
  49.             tb[rta->rta_type] = rta;
  50.         rta = RTA_NEXT(rta,len);
  51.     }
  52.     if (len)
  53.         fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
  54.     
  55.     return;
  56. }

  57. const char *addr_to_mac(unsigned char *addr, int alen, char *buf, ssize_t blen)
  58. {
  59.     int i;
  60.     int l;

  61.     l = 0;
  62.     for (i = 0; i < alen; i++) {
  63.         if (i==0) {
  64.             snprintf(buf+l, blen, "%02x", addr[i]);
  65.             blen -= 2;
  66.             l += 2;
  67.         } else {
  68.             snprintf(buf+l, blen, ":%02x", addr[i]);
  69.             blen -= 3;
  70.             l += 3;
  71.         }
  72.     }
  73.     return buf;
  74. }

  75. static void read_netlink_message(int fd)
  76. {
  77.     char buff[128 * 1024] = {0};
  78.     char *buf[1024] = {0};
  79.     struct nlmsghdr *nh;
  80.     struct ndmsg *ndmsg;
  81.     int read_size;
  82.     int len = 0;    
  83.     struct rtattr *tb[NDA_MAX + 1];
  84.                 
  85.     read_size = read(fd, buff, sizeof(buff));
  86.     if (read_size < 0) {
  87.         return;
  88.     }                    
  89.         
  90.     for (nh = (struct nlmsghdr*)buff; NLMSG_OK(nh, read_size);
  91.         nh = NLMSG_NEXT(nh, read_size)) {
  92.         switch (nh->nlmsg_type) {
  93.         case RTM_NEWNEIGH:
  94.             printf("add new arp cache\n");
  95.             ndmsg = NLMSG_DATA(nh);
  96.             if (ndmsg->ndm_family == AF_INET) {
  97.                 len = nh->nlmsg_len - NLMSG_SPACE(sizeof(struct ndmsg));
  98.                 arp_parse_rattr(tb, NDA_MAX, NDA_RTA(ndmsg), len);
  99.                     if (tb[NDA_DST]) {
  100.                         printf(""FMT_IP" %d\n", STR_IP(*(RTA_DATA(tb[NDA_DST]))), RTA_PAYLOAD(tb[NDA_DST]));
  101.                     }
  102.                     if (tb[NDA_LLADDR]) {
  103.                         printf("%s %d\n", addr_to_mac(RTA_DATA(tb[NDA_LLADDR]),
  104.                             RTA_PAYLOAD(tb[NDA_LLADDR]), buf, sizeof(buf)), RTA_PAYLOAD(tb[NDA_LLADDR]));
  105.                     }
  106.             }
  107.             break;
  108.         default:
  109.             break;
  110.         }
  111.     }
  112.     
  113.     return;    
  114. }

  115. int main(void)
  116. {
  117.     int fd;
  118.     struct sockaddr_nl sa;
  119.     fd_set rd_set;
  120.     int ret;
  121.     
  122.     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  123.     
  124.     bzero(&sa, sizeof(sa));
  125.     
  126.     sa.nl_family = AF_NETLINK;
  127.     sa.nl_groups = RTM_NEWNEIGH | RTM_DELNEIGH;
  128.     
  129.     if ((bind(fd, (struct sockaddr *)&sa, sizeof(sa))) != 0) {
  130.         perror("bind");
  131.         return -1;
  132.     }
  133.     
  134.     while (1) {
  135.         FD_ZERO(&rd_set);
  136.         FD_SET(fd, &rd_set);
  137.         ret = select(fd + 1, &rd_set, NULL, NULL, NULL);
  138.         if (ret < 0) {
  139.             printf("select error\n");
  140.             break;
  141.         } else if (ret > 0) {
  142.             if (FD_ISSET(fd, &rd_set)) {
  143.                 read_netlink_message(fd);
  144.             }
  145.         }
  146.     }
  147.     
  148.     close(fd);
  149.     return 0;
  150. }

阅读(3989) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~