打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
发现局域网所有主机
遇到问题:
1。接入一个不知道网段网段的局域网;
2。需要发现局域网的所有的ip;

处理步骤
1。用原始套接字,监听arp消息,获取接口的mac地址;
2。根据收到的arp广播,可以从arp协议的sip字段,提取出源ip;
3。根据ip地址,然后掩码上24位,然后发送从1 ~255的地址的arp 广播;
4。通过收到的arp repy 来获取所有的局域网地址;

5。如果收到了新的ip地址24位掩码。不等于原来保持的ip地址24位掩码,掩码就变成16位;然后发送65535个报文;(猜想掩码位16位做处理)


下面代码是参考,需要用我个人封装好的libevent库才可以运行,如果需要可以联系我~~

  1. #include <unistd.h>  
  2. #include <errno.h>  
  3. #include <netdb.h>  
  4. #include <signal.h>  
  5. #include <sys/socket.h>  
  6. #include <sys/poll.h>  
  7. #include <sys/ioctl.h>  
  8. #include <netinet/if_ether.h>  
  9. #include <net/if_arp.h>  
  10. #include <netinet/udp.h>  
  11. #include <netinet/ip.h>  
  12. #include <stdio.h>  
  13. #include <stdarg.h>  
  14. #include <net/if.h>  
  15. #include <string.h>  
  16. #include <arpa/inet.h>  
  17. #include <map>  
  18. #include <iostream>  
  19.   
  20. #include <fcntl.h>  
  21. using namespace std;  
  22. #include "cneos_event.h"  
  23. enum {  
  24.     ARP_MSG_SIZE = 0x2a  
  25. };  
  26. typedef map<int, string> ARP;  
  27.   
  28. ARP arp_table;  
  29.   
  30. #define MASK_16 0xffff0000  
  31. #define MASK_24 0xffffff00  
  32. int network=0;  
  33. uint32_t sip;  
  34. uint8_t smac[6];  
  35.   
  36. char interface[] = "eno16777984";     
  37.   
  38.   
  39.   
  40. char* strncpy_IFNAMSIZ(char *dst, const char *src)  
  41. {  
  42. #ifndef IFNAMSIZ  
  43.     enum { IFNAMSIZ = 16 };  
  44. #endif  
  45.     return strncpy(dst, src, IFNAMSIZ);  
  46. }  
  47.   
  48. struct arpMsg {  
  49.     /* Ethernet header */  
  50.     uint8_t h_dest[6]; /* 00 destination ether addr */  
  51.     uint8_t h_source[6]; /* 06 source ether addr */  
  52.     uint16_t h_proto; /* 0c packet type ID field */  
  53.   
  54.         /* ARP packet */  
  55.     uint16_t htype; /* 0e hardware type (must be ARPHRD_ETHER) */  
  56.     uint16_t ptype; /* 10 protocol type (must be ETH_P_IP) */  
  57.     uint8_t hlen; /* 12 hardware address length (must be 6) */  
  58.     uint8_t plen; /* 13 protocol address length (must be 4) */  
  59.     uint16_t operation; /* 14 ARP opcode */  
  60.     uint8_t sHaddr[6]; /* 16 sender's hardware address */  
  61.     uint8_t sInaddr[4]; /* 1c sender's IP address */  
  62.     uint8_t tHaddr[6]; /* 20 target's hardware address */  
  63.     uint8_t tInaddr[4]; /* 26 target's IP address */  
  64.     uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */  
  65. } PACKED;  
  66. const int const_int_1 = 1;  
  67.   
  68. //设置套接子为广播  
  69. int setsockopt_broadcast(int fd)  
  70. {  
  71.     return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1));  
  72. }  
  73.   
  74. char* safe_strncpy(char *dst, const char *src, size_t size)  
  75. {  
  76.     if (!size) return dst;  
  77.     dst[--size] = '\0';  
  78.     return strncpy(dst, src, size);  
  79. }  
  80. int set_socket_bloking(int socket)  
  81. {  
  82.     int flags = fcntl(socket, F_GETFL, 0);   
  83.     fcntl(socket, F_SETFL, flags & ~O_NONBLOCK);  
  84. }  
  85.   
  86.   
  87. //发送ARP请求  
  88. int arpping(int s,uint32_t test_ip, uint32_t from_ip)  
  89. {  
  90.     int timeout_ms;  
  91.   
  92.     int rv = 1; /* "no reply received" yet */  
  93.     struct sockaddr addr; /* for interface name */  
  94.     struct arpMsg arp;  
  95.      
  96.     //构造ARP数据包  
  97.     /* send arp request */  
  98.     memset(&arp, 0, sizeof(arp));  
  99.     memset(arp.h_dest, 0xff, 6); /* MAC DA */  
  100.     memcpy(arp.h_source, smac, 6); /* MAC SA */  
  101.     arp.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */  
  102.     arp.htype = htons(ARPHRD_ETHER); /* hardware type */  
  103.     arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */  
  104.     arp.hlen = 6; /* hardware address length */  
  105.     arp.plen = 4; /* protocol address length */  
  106.     arp.operation = htons(ARPOP_REQUEST); /* ARP op code */  
  107.     memcpy(arp.sHaddr, smac, 6); /* source hardware address */  
  108.     memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */  
  109.     /* tHaddr is zero-fiiled */ /* target hardware address */  
  110.     memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */  
  111.    //构造目标网络地址  
  112.     memset(&addr, 0, sizeof(addr));  
  113.     safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));  
  114.     //set_socket_bloking(s);  
  115.       
  116.     int try_count = 0;  
  117.     while (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0)  
  118.     {  
  119.         printf("send to error\n");  
  120.         try_count++;  
  121.         if (try_count == 1000) break;  
  122.     }  
  123.           
  124.     return rv;  
  125. }  
  126.   
  127.   
  128. int read_interface(const char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)  
  129. {  
  130.     int fd;  
  131.     struct ifreq ifr;  
  132.     struct sockaddr_in *our_ip;  
  133.   
  134.     memset(&ifr, 0, sizeof(ifr));  
  135.     fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);  
  136.   
  137.     ifr.ifr_addr.sa_family = AF_INET;  
  138.     strncpy_IFNAMSIZ(ifr.ifr_name, interface);  
  139.     if (addr) {  
  140.         if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) {  
  141.             perror("ioctl");  
  142.             close(fd);  
  143.             return -1;  
  144.         }  
  145.         our_ip = (struct sockaddr_in *) &ifr.ifr_addr;  
  146.         *addr = our_ip->sin_addr.s_addr;  
  147.         printf("ip of %s = %s \n", interface, inet_ntoa(our_ip->sin_addr));  
  148.     }  
  149.   
  150.     if (ifindex) {  
  151.         if (ioctl(fd, SIOCGIFINDEX, &ifr) != 0) {  
  152.             close(fd);  
  153.             return -1;  
  154.         }  
  155.         printf("adapter index %d", ifr.ifr_ifindex);  
  156.         *ifindex = ifr.ifr_ifindex;  
  157.     }  
  158.   
  159.     if (arp) {  
  160.         if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) {  
  161.             close(fd);  
  162.             return -1;  
  163.         }  
  164.         memcpy(arp, ifr.ifr_hwaddr.sa_data, 6);  
  165.         printf("adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x\n",  
  166.             arp[0],arp[1],arp[2],arp[3],arp[4], arp[5]);  
  167.     }  
  168.     close(fd);  
  169.     return 0;  
  170. }  
  171.   
  172. void ReadEventCb(struct bufferevent *bev, void *data)  
  173. {  
  174.     char buffer[2000];  
  175.     int len = GetReadBuffer(buffer, sizeof(buffer));  
  176.     if (len >= sizeof(struct arpMsg))  
  177.     {  
  178.         struct arpMsg *arp1 = (struct arpMsg *)buffer;   
  179.         char mac[20];  
  180.         sprintf(mac,"%02x:%02x:%02x:%02x:%02x:%02x",  
  181.             arp1->sHaddr[0],  
  182.             arp1->sHaddr[1],  
  183.             arp1->sHaddr[2],  
  184.             arp1->sHaddr[3],  
  185.             arp1->sHaddr[4],  
  186.             arp1->sHaddr[5]);          
  187.         //if (arp1->htype == htons(0x0001) && arp1->h_proto == htons(0x0800))  
  188.         int sip = ntohl(((int *)(arp1->sInaddr))[0]);  
  189.         if (sip)  
  190.         {  
  191.           
  192.             if (sip&MASK_24 != network && arp_table.find(sip) == arp_table.end()) {  
  193.                 network = sip >> 8 << 8;      
  194.                 printf("ip of %s %d.%d.%d.%d \n", mac, arp1->sInaddr[0], arp1->sInaddr[1], arp1->sInaddr[2], arp1->sInaddr[3]);  
  195.                 for (int i = 1; i < 255; i++)  
  196.                 {  
  197.                     arpping(bufferevent_getfd(bev), htonl(network + i), htonl(network+254));  
  198.                 }  
  199.             }  
  200.             arp_table[sip] = mac;  
  201.   
  202.         }  
  203.     }  
  204.   
  205. }  
  206.   
  207. int main(int argc, char **argv)  
  208. {  
  209.     uint32_t TEST_IP =1||inet_addr(argv[1]);  
  210.         //网卡名字  
  211.   
  212.     read_interface(interface, NULL, &sip, smac); //根据网卡名字读取本地的mac地址和ip地址  
  213.       
  214.     int arp_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));   
  215.     if (arp_fd <=0 || setsockopt_broadcast(arp_fd) == -1) {  
  216.         perror("cannot enable bcast on raw socket");  
  217.     }  
  218.     evutil_make_socket_nonblocking(arp_fd);  
  219.     AddBuffEvent(arp_fd, ReadEventCb, NULL, NULL,NULL);  
  220.     event_run();  
  221.       
  222.     return 0;  
  223. }  



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
IP冲突检测程序源码及分析
socket修改本机IP
ioctl函数详解
LINUX下获取IP地址和MAC地址
Linux c 获取网络接口IP地址
TX2/Linux下can总线的接收与发送命令和C程序实例_candump命令
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服