📄 arp_tab.cpp
字号:
#include "arp_tab.h"ArpTab::ArpTab(QWidget *parent) : QWidget(parent){ arp_ip_check = new QCheckBox( this, "arp_ip_check" ); arp_ip_check->setGeometry( QRect( 10, 40, 81, 21 ) ); arp_ip_check->setText( tr( "Specify IP:" ) ); work_mode = new QButtonGroup( this, "work_mode" ); work_mode->setGeometry( QRect( 10, 0, 210, 40 ) ); work_mode->setTitle( tr( "Work Mode" ) ); hostScan_RadioButton = new QRadioButton( work_mode, "loopScan_RadioButton" ); hostScan_RadioButton->setGeometry( QRect( 40, 10, 70, 22 ) ); hostScan_RadioButton->setText( tr( "Host Scan" ) ); arpCheat_RadioButton = new QRadioButton( work_mode, "arpCheat_RadioButton" ); arpCheat_RadioButton->setGeometry( QRect( 130, 10, 72, 22 ) ); arpCheat_RadioButton->setText( tr( "ARP Cheat" ) ); arp_ip_lineedit = new QLineEdit( this, "arp_ip_lineedit" ); arp_ip_lineedit->setEnabled( FALSE ); arp_ip_lineedit->setGeometry( QRect( 100, 40, 110, 26 ) ); arp_ip_lineedit->setText( tr( "" ) ); arp_eth_lineedit = new QLineEdit( this, "arp_Eth_lineedit" ); arp_eth_lineedit->setEnabled( FALSE ); arp_eth_lineedit->setGeometry( QRect( 100, 70, 110, 26 ) ); arp_eth_lineedit->setText( tr( "eth0" ) ); disp_arp = new QListView( this, "disp_arp" ); disp_arp->addColumn( tr( "Seq" ) ); disp_arp->setGeometry( QRect( 10, 100, 210, 140 ) ); arp_eth_check = new QCheckBox( this, "arp_eth_check" ); arp_eth_check->setGeometry( QRect( 10, 70, 70, 20 ) ); arp_eth_check->setText( tr( "Specify eth:" ) ); ARP_start = new QPushButton( this, "ARP_start" ); ARP_start->setGeometry( QRect( 30, 250, 60, 32 ) ); ARP_start->setText( tr( "Start" ) ); ARP_clear = new QPushButton( this, "ARP_clear" ); ARP_clear->setGeometry( QRect( 140, 250, 60, 32 ) ); ARP_clear->setText( tr( "Clear" ) ); connect( ARP_start, SIGNAL( clicked() ), this, SLOT( start_arp() ) ); connect( ARP_clear, SIGNAL( clicked() ), this, SLOT( clear_arp() ) ); connect( arp_eth_check, SIGNAL( clicked() ), this, SLOT( enableEth() ) ); connect( arp_ip_check, SIGNAL( clicked() ), this, SLOT( enableIP() ) ); connect( hostScan_RadioButton, SIGNAL( clicked() ), this, SLOT( enableHostScan() ) ); connect( arpCheat_RadioButton, SIGNAL( clicked() ), this, SLOT( enableArpCheat() ) ); disp_arp->setSorting( 1, FALSE); libnet = NULL; pcap = NULL; hostScan_RadioButton ->setChecked(TRUE); workmode_flag = HOSTSCAN; //工作模式标志 scan_flag = TRUE; //开启循环扫描标志 stopped = FALSE;}ArpTab::~ArpTab(){// libnet_destroy(libnet);// pcap_close(pcap);}void ArpTab::run(){ if(!stopped) { if(workmode_flag == HOSTSCAN) { host_scan(); } else { arp_cheat(); } } stopped = FALSE;}void ArpTab::stop(){ stopped = TRUE; libnet_destroy(libnet); pcap_close(pcap);}void ArpTab::start_arp(){ if(!running()) { start(); }}void ArpTab::clear_arp(){ disp_arp->clear();}void ArpTab::enableEth(){ if(arp_eth_check->isChecked()) { arp_eth_lineedit->setEnabled(TRUE); } else { arp_eth_lineedit->setEnabled(FALSE); }}void ArpTab::enableIP(){ if(arp_ip_check->isChecked()) { arp_ip_lineedit->setEnabled(TRUE); scan_flag = FALSE; } else { arp_ip_lineedit->setEnabled(FALSE); scan_flag = TRUE; }}void ArpTab::enableHostScan(){ if(hostScan_RadioButton -> isChecked()) { workmode_flag = HOSTSCAN; } else { workmode_flag = ARPCHEAT; }}void ArpTab::enableArpCheat(){ if(arpCheat_RadioButton -> isChecked()) { workmode_flag = ARPCHEAT; } else { workmode_flag = HOSTSCAN; }}void ArpTab::display(QString output){ list_item = new QListViewItem(disp_arp); list_item -> setText(0, output);}void ArpTab::quit(){ libnet_destroy(libnet); pcap_close(pcap); exit();}void ArpTab::eth_addr_itoa(char *dst_eth_str, u_int8_t *src_eth){//将u_int8_t型MAC地址转化成字符串型 00:16:d3:40:69:8b int i,j; for (i = 0 , j = 0; i < ETH_ALEN - 1 ; i++, j += 3) { sprintf(dst_eth_str+j, "%.2x", (u_int8_t) src_eth[i]); sprintf(dst_eth_str+j+2, ":"); } sprintf(dst_eth_str+j, "%.2x", (u_int8_t) src_eth[ETH_ALEN - 1]);}void ArpTab::ip_addr_itoa(char *dst_ip_str, u_int8_t *src_ip){//将u_int8_t型IP地址转化成字符串型 25.20.227.12 sprintf(dst_ip_str, "%d.%d.%d.%d",src_ip[0], src_ip[1],src_ip[2],src_ip[3]);}void ArpTab::arp_cheat(){ u_int8_t eth_src[ETH_ALEN] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }; // ^_^ u_int8_t eth_dst[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* broadcast */ char src_eth_str[20]; char dst_eth_str[20]; u_int8_t ip_src[IP_ALEN]; u_int8_t ip_dst[IP_ALEN]; char src_ip_str[20]; char dst_ip_str[20]; u_int8_t ip_my[IP_ALEN]; u_int32_t my_ip; u_int32_t src_ip; char *arg_ip = NULL; //目的IP参数传递 libnet_ptag_t arp = 0, eth = 0; char errbuf[LIBNET_ERRBUF_SIZE]; int i, c, seq; device = (char *)arp_eth_lineedit->text().ascii(); if (device == NULL) { device = pcap_lookupdev(errbuf); if (device == NULL) { error_buf.sprintf("pcap_lookupdev() failed: %s\n", errbuf); display(error_buf); quit(); } } // open libnet libnet = libnet_init(LIBNET_LINK, device, errbuf); if (libnet == NULL) { error_buf.sprintf("libnet_init() failed: %s", errbuf); display(error_buf); exit(); } my_ip = libnet_get_ipaddr4(libnet); memcpy(ip_my, (char *) &my_ip, IP_ALEN); if(scan_flag == TRUE) { src_ip = libnet_get_ipaddr4(libnet); memcpy(ip_src, (char *) &src_ip, IP_ALEN); seq = 256; //scan the network segment } else { // get dst ip address arg_ip = (char *)arp_ip_lineedit->text().ascii(); src_ip = libnet_name2addr4(libnet, arg_ip, LIBNET_DONT_RESOLVE); memcpy(ip_src, (char *) &src_ip, IP_ALEN); seq = 3; //detect the destination IP } /* 网关IP */ ip_dst[0] = ip_src[0]; ip_dst[1] = ip_src[1]; ip_dst[2] = ip_src[2]; ip_dst[3] = 1; for (i = 1; i < seq; i++) //发n个ARP请求包 { if(scan_flag == TRUE) { ip_src[3] = i; //欺骗下一个IP地址 if(i == ip_my[3]) //除了本机IP continue; } arp = libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETH_ALEN, IP_ALEN, ARPOP_REQUEST, eth_src, ip_src, eth_dst, ip_dst, NULL, 0, libnet, 0); if (arp == -1) { error_buf.sprintf( "Can't build ARP header: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } eth = libnet_build_ethernet(eth_dst, eth_src, ETHERTYPE_ARP, NULL, 0, libnet, 0); /* 构造物理帧头 */ if (eth == -1) { error_buf.sprintf("Can't build ethernet header: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } c = libnet_write(libnet); if (c == -1) { error_buf.sprintf("Can't send ARP packet: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } //转化成字符串型MAC地址 00:16:d3:40:69:8b eth_addr_itoa(src_eth_str, eth_src); eth_addr_itoa(dst_eth_str, eth_dst); ip_addr_itoa(src_ip_str, ip_src); ip_addr_itoa(dst_ip_str, ip_dst); output_buf.sprintf("%d: Tell %s Who has %s? Source: %s Destination: %s \n", i, src_ip_str, dst_ip_str, src_eth_str, dst_eth_str); display(output_buf); libnet = libnet_init(LIBNET_LINK, device, errbuf); }}void ArpTab::host_scan(){ char src_eth_str[20], dst_eth_str[20]; //保存发送包物理地址 u_int8_t eth_src[ETH_ALEN]; u_int8_t eth_dst[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //目的MAC地址,广播 char catch_src_eth[20], catch_dst_eth[20]; //保存抓取包物理地址 char catch_src_ip[20]; //保存抓取包源IP地址 char *src_ip_str = NULL; char *dst_ip_str = NULL; u_int32_t dst_ip; u_int32_t src_ip; u_int8_t dst_ip_array[IP_ALEN]; char *device = NULL; int i, c, seq; libnet_ptag_t arp = 0, eth = 0; struct libnet_ether_addr* src_eth_addr = NULL; char errbuf[LIBNET_ERRBUF_SIZE]; int pcap_fd; u_int8_t *packet = NULL; //数据包描述符 struct pcap_pkthdr pc_hdr; //数据包结构 struct timeval timeout; //时间戳 struct bpf_program filter_code; //过滤结构 struct arp_header *arp_hdr = NULL; //arp报头结构 bpf_u_int32 local_net, netmask; //pcap定义的本机网络号和掩码 fd_set read_set; int timed_out; struct host_info host_alive[256]; bool alive_flag = FALSE; device = (char *)arp_eth_lineedit->text().ascii(); if (device == NULL) {//如果没有指定网卡设备,则自动获取 device = pcap_lookupdev(errbuf); if (device == NULL) { error_buf.sprintf("pcap_lookupdev() failed: %s\n", errbuf); display(error_buf); quit(); } } // open libnet libnet = libnet_init(LIBNET_LINK_ADV, device, errbuf); if (libnet == NULL) { error_buf.sprintf("libnet_init() failed: %s", errbuf); display(error_buf); exit(); } if(!scan_flag) { dst_ip_str = (char *)arp_ip_lineedit->text().ascii(); dst_ip = libnet_name2addr4(libnet, dst_ip_str, LIBNET_DONT_RESOLVE); // 把目的IP地址字符串形式转化成网络顺序字节形式的数据 if ((int)dst_ip == -1) { error_buf.sprintf("Bad destination IP address (%s).\n", libnet_geterror(libnet)); display(error_buf); quit(); } } src_ip = libnet_get_ipaddr4(libnet); if ((int)src_ip == -1) { error_buf.sprintf("Can't determine source IP address (%s).\n", libnet_geterror(libnet)); display(error_buf); quit(); } src_eth_addr = libnet_get_hwaddr(libnet); if (src_eth_addr == NULL) { error_buf.sprintf("Can't get source MAC address (%s).\n", libnet_geterror(libnet)); display(error_buf); quit(); } for(i = 0; i < ETH_ALEN; i++) //MAC地址 { eth_src[i] = src_eth_addr->ether_addr_octet[i]; } //转化成字符串型MAC地址 00:16:d3:40:69:8b eth_addr_itoa(src_eth_str, eth_src); eth_addr_itoa(dst_eth_str, eth_dst); pcap = pcap_open_live(device, //设备描述符 MAX_LEN, //捕获包最大长度 1, //开启混杂模式 1000, //延时(毫秒) errbuf); if (pcap == NULL) { error_buf.sprintf("pcap_open_live() failed: %s", errbuf); display(error_buf); quit(); } if (pcap_lookupnet(device, &local_net, &netmask, errbuf) == -1) { error_buf.sprintf( "pcap_lookupnet(): %s", errbuf); display(error_buf); quit(); } if (pcap_compile(pcap, &filter_code, ARP_FILTER, 1, netmask) == -1) { error_buf.sprintf("pcap_compile(): %s", pcap_geterr(pcap)); display(error_buf); quit(); } if (pcap_setfilter(pcap, &filter_code) == -1) { error_buf.sprintf("pcap_setfilter(): %s", pcap_geterr(pcap)); display(error_buf); quit(); } timeout.tv_sec = MAX_TIMEOUT; timeout.tv_usec = 0; pcap_fd = pcap_fileno(pcap); //由pcap句柄返回其文件描述符 if(scan_flag == TRUE) { memcpy(dst_ip_array, (char *) &local_net, IP_ALEN); //取本机所在网络地址 seq = 256; //scan the network segment } else { seq = 3; //detect the destination IP } for(i = 0; i < 256; i++) {//存活主机标志清零 host_alive[i].host_alive = 0; } for (i = 1; i < seq; i++) //发n个ARP请求包 { usleep(300); if(scan_flag == TRUE) { dst_ip_array[3] = i; //扫描下一个IP地址 memcpy((char *)&dst_ip, dst_ip_array, IP_ALEN); //目的地址 dst_ip_str = libnet_addr2name4(dst_ip, LIBNET_DONT_RESOLVE); } arp = libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETH_ALEN, IP_ALEN, ARPOP_REQUEST, eth_src, (u_int8_t*) &src_ip, eth_dst, (u_int8_t*) &dst_ip, NULL, 0, libnet, 0); if (arp == -1) { error_buf.sprintf("Can't build ARP header: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } eth = libnet_autobuild_ethernet(eth_dst, ETHERTYPE_ARP, libnet); if (eth == -1) { error_buf.sprintf("Can't build ethernet header: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } c = libnet_write(libnet); if (c == -1) { error_buf.sprintf("Can't send ARP packet: %s\n", libnet_geterror(libnet)); display(error_buf); quit(); } libnet = libnet_init(LIBNET_LINK_ADV, device, errbuf); src_ip_str = libnet_addr2name4(src_ip, LIBNET_DONT_RESOLVE); output_buf.sprintf("ARP Request: Who has %s? Tell %s Source: %s Destination: %s \n", dst_ip_str, src_ip_str, src_eth_str, dst_eth_str); display(output_buf); //开始由PCAP抓包 FD_ZERO(&read_set); FD_SET(pcap_fd, &read_set); for(timed_out = 0; !timed_out ;) { c = select(pcap_fd + 1, &read_set, 0, 0, &timeout); //等待pcap文件描述符的响应数据 switch (c) {//异常处理 case -1: {//出错 error_buf.sprintf("select() %s\n", strerror(errno)); display(error_buf); quit(); } case 0: {//在timeout时间内没有数据响应,返回for循环 timed_out = 1; continue; } default: if (FD_ISSET(pcap_fd, &read_set) == 0) { timed_out = 1; continue; } } packet = (u_int8_t *)pcap_next(pcap, &pc_hdr); //捕获下一个包 if (packet == NULL) { continue; } arp_hdr = (struct arp_header *)(packet + ETH_HEAD_LEN); ip_addr_itoa(catch_src_ip, arp_hdr->src_ip); if( ntohs(arp_hdr->ar_op) == 2) {//收到响应包 eth_addr_itoa(catch_src_eth, arp_hdr->src_eth); eth_addr_itoa(catch_dst_eth, arp_hdr->dst_eth); output_buf.sprintf("ARP Reply: %s is at %s Source: %s Destination: %s \n", catch_src_ip , catch_src_eth, catch_src_eth, catch_dst_eth ); display(output_buf); alive_flag = TRUE; i = arp_hdr->src_ip[3]; host_alive[i].host_alive = 1; strncpy( host_alive[i].ip_str , catch_src_ip, strlen(catch_src_ip)); strncpy( host_alive[i].eth_str , catch_src_eth, strlen(catch_src_eth)); break; } } } for(i = 0; i < 256; i++) { if(host_alive[i].host_alive == 1) { output_buf.sprintf("%s(%s) is alive\n", host_alive[i].ip_str, host_alive[i].eth_str); display(output_buf); } } if(!alive_flag) { output_buf.sprintf("NO host is alive\n" ); display(output_buf); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -