📄 framesniffer.cpp
字号:
/* This file is part of AirFart. AirFart is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. AirFart is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with AirFart; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "framesniffer.h"#include "printchars.h"/****************************************************************************/void *start_sniffing_thread( void *arg ){ printf( "start_sniffing_thread() Called!\n" ); frame_sniffer *sniffer = (frame_sniffer*)arg; sleep(1); if( false == sniffer->start_sniffing_loop() ) { printf( "sniffing loop bombed out!\n" ); }}/****************************************************************************/bool frame_sniffer::start_sniffing(){ pthread_t thread_id; int err; if( (err = pthread_create( &thread_id, NULL, start_sniffing_thread, this ) ) ) { printf( "Error: Could not spawn sniffing thread...\n" ); return false; } else { printf( "Sniffing thread spawned successfully!\n" ); return true; }}/****************************************************************************/bool frame_sniffer::start_sniffing_loop(){ if( -1 == go_monitor_mode() ) return false; if( -1 == set_socket() ) return false; if( -1 == bind_socket() ) return false; unsigned int avs_header_len; int i, j, bytes_read, strength_percent; char *ss_id; unsigned char src_eth_addr[ETH_ADDR_LEN], dst_eth_addr[ETH_ADDR_LEN]; #ifdef DEBUG_SNIFFER printf( "Reading from device...\n" ); #endif bytes_read = 0; for(;;) { bytes_read = recv (skt, msgbuf, MAX_BUFFER_SIZE, 0 ); if( bytes_read == -1 ) { printf( "Warning: Could not read from device." ); printf( "Sleeping for retry!\n" ); sleep(1); continue; } #ifdef DEBUG_SNIFFER printf( "_________________________________________" ); printf( "_________________________\n" ); printf( "Captured a frame: %d bytes\n", bytes_read ); print_chars( "Frame contents:", msgbuf, bytes_read ); #endif if( -1 == error_check_frame( msgbuf, bytes_read ) ) { #ifndef DEBUG_SNIFFER printf( "Warning: Dropped a frame.\n" ); print_chars( " Frame Contents:", msgbuf, bytes_read ); printf( "\n" ); #endif continue; } /* Extract all the info we need from the frame (strength, eth addrs) */ wlan_hdr = (wlan_header*)msgbuf; wlan_hdr->signal_strength = ntohl( wlan_hdr->signal_strength ); wlan_hdr->signal_strength_type = ntohl( wlan_hdr->signal_strength_type ); wlan_hdr->signal_noise = ntohl( wlan_hdr->signal_noise ); memcpy( dst_eth_addr, msgbuf+DST_ETH_ADDR_OFFSET, ETH_ADDR_LEN ); memcpy( src_eth_addr, msgbuf+SRC_ETH_ADDR_OFFSET, ETH_ADDR_LEN ); ss_id = get_ss_id( msgbuf ); #ifdef PRISM3 wlan_hdr->signal_strength *= 2.55; #endif strength_percent = signal_strength_to_percent( wlan_hdr->signal_strength_type, wlan_hdr->signal_strength ); #ifdef DEBUG_SNIFFER printf( " src eth: " ); print_eth_addr( src_eth_addr ); printf( "\n" ); printf( " strength: %d (%d\%)\n", wlan_hdr->signal_strength , strength_percent ); printf( " type: %d\n", wlan_hdr->signal_strength_type ); printf( " noise: %d\n", wlan_hdr->signal_noise ); #endif /* Pass the eth address and sig strength to our stats collector */ stats->add_packet( src_eth_addr, ss_id, strength_percent ); }}/*******************************************************************************/// NOTE: uses local (private) variable: foreign_ss_id (class member)char *frame_sniffer::get_ss_id( unsigned char *buf ){ #ifdef DEBUG_SNIFFER printf( "frame_sniffer::get_ss_id(): Warning: SSID detection is under construction. Values may be incorrect.\n" ); #endif int ss_id_len = 0; char none[] = "(none)"; // did we really get an SSID here? if( buf[SSID_VALID_OFFSET] != SSID_VALID ) { strcpy( foreign_ss_id, none ); ss_id_len = 6; } else { memcpy( &ss_id_len, buf+SSID_LEN_OFFSET, 1 ); memcpy( foreign_ss_id, buf+SSID_OFFSET, ss_id_len ); foreign_ss_id[ ss_id_len ] = '\0'; } #ifdef DEBUG_SNIFFER printf( "frame_sniffer:get_ss_id(): ss id len: %d\n", ss_id_len ); #endif if( ss_id_len == 0 ) { strcpy( foreign_ss_id, none ); ss_id_len = 6; } // cleanup the ss_id for(int i=0; i<ss_id_len; i++ ) if( ! isprint( foreign_ss_id[i] ) ) foreign_ss_id[i] = '.'; #ifdef DEBUG_SNIFFER printf( "foreign_ss_id: %s\n", foreign_ss_id ); #endif return foreign_ss_id;}/********************************************************************************/int frame_sniffer::go_monitor_mode( int channel ){ char monitor_command[255]; int wlan_ret_val; FILE *wlanctl; #ifdef DEBUG_SNIFFER printf( "Putting device in monitor mode... " ); #endif sprintf( monitor_command, "wlanctl-ng wlan0 lnxreq_wlansniff enable=true channel=%d wlanheader=true;", channel ); sprintf( monitor_command, "%s ifconfig wlan0 up", monitor_command ); #ifndef DEBUG_SNIFFER sprintf( monitor_command, "%s %s", monitor_command, " > /dev/null 2>&1" ); #endif wlan_ret_val = system( monitor_command ); /* // run the command and capture the output // TODO check for result=refused (err, result != success) wlanctl = popen( monitor_command, "r" ); fclose( wlanctl ); */ #ifdef DEBUG_SNIFFER printf( " (command returned %d) ", wlan_ret_val ); #endif if( wlan_ret_val != 0 ) { printf( "Could not put the card in monitor mode!\n" ); printf( " The device is not present or 'wlanctl-ng' is not in your path or the device refused.\n" ); return -1; } else { #ifdef DEBUG_SNIFFER printf( "Done.\n" ); #endif return 0; }}/********************************************************************************/int frame_sniffer::set_socket(){ #ifdef DEBUG_SNIFFER printf( "Opening raw socket to device...\n" ); #endif skt = 1; skt = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (skt == -1) { printf("ERROR: Could not open connection to the network card!\n"); return -1; } else { #ifdef DEBUG_SNIFFER printf( "Done.\n" ); #endif return 0; }}/********************************************************************************/int frame_sniffer::bind_socket(){ #ifdef DEBUG_SNIFFER printf( "Binding socket to device... " ); #endif int bind_result; struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = 0; sll.sll_protocol = htons(ETH_P_ALL); bind_result = bind( skt, (struct sockaddr *) &sll, sizeof(sll) ); if( bind_result == -1 ) { printf( "ERROR: Could not bind the socket!\n" ); return -1; } else { #ifdef DEBUG_SNIFFER printf( "Done.\n" ); #endif return 0; }}/********************************************************************************/void frame_sniffer::print_eth_addr( unsigned char *eth_addr ){ printf( "%x:%x:%x:%x:%x:%x", eth_addr[0],eth_addr[1],eth_addr[2], eth_addr[3],eth_addr[4],eth_addr[5] );}/********************************************************************************/void frame_sniffer::set_stats_collector( Stats *s){ stats = s;}/********************************************************************************/int frame_sniffer::error_check_frame( unsigned char *frame, int len ){ unsigned char bcast_eth_addr[ETH_ADDR_LEN] = BCAST_ADDR; unsigned char dot11_ident[DOT11_IDENT_LEN] = DOT11_IDENT; int avs_header_len; /* Check for the 802.11 ident value at the beginning of the packet */ if( 0 != memcmp( frame+DOT11_IDENT_OFFSET, dot11_ident, DOT11_IDENT_LEN ) ) { #ifdef DEBUG_SNIFFER printf( " -- Error: this is not an 802.11 packet --\n" ); #endif return -1; } /* Extract the AVS header len from the wlan header */ memcpy( &avs_header_len, frame+AVS_HEADER_LEN_OFFSET, 4 ); avs_header_len = ntohl( avs_header_len ); /* If the extracted avs header len isn't 64, we've got a malformed * packet on our hands (or the card isn't passing the wlan header */ if( avs_header_len != AVS_HEADER_LEN ) { #ifdef DEBUG_SNIFFER printf( " -- Error in AVS header length -- \n" ); printf( " -- Expected %d, got %d -- \n", AVS_HEADER_LEN, avs_header_len ); #endif return -1; } /* We are expecting the ethernet frame to be big enough to * have the source eth addr in it. If it ain't, it's an error */ // FIXME: We are not getting 1/100 packets for this reason if( len < SRC_ETH_ADDR_OFFSET+ETH_ADDR_LEN ) { #ifdef DEBUG_SNIFFER printf( " -- Error: frame appears too short -- \n" ); #endif return -1; } /* We are expecting the ethernet frame to be big enough to * have the destination eth addr in it. If it ain't, it's an error */ if( len < DST_ETH_ADDR_OFFSET+ETH_ADDR_LEN ) { #ifdef DEBUG_SNIFFER printf( " -- Error: frame appears too short -- \n" ); #endif return -1; } return 0;}/********************************************************************************/int frame_sniffer::signal_strength_to_percent( int signal_type, int signal_strength ){ int percent; switch( signal_type ) { case SIGNAL_TYPE_NONE: percent = 0; printf( "Warning: Your wireless ethernet card does not report signal strengths!\n" ); break; case SIGNAL_TYPE_NORMALIZED_RSSI: percent = (signal_strength * 100) / MAX_NORMALIZED_RSSI_VALUE; break; case SIGNAL_TYPE_DBM: signal_strength = -signal_strength; signal_strength -= MIN_DBM_VALUE; percent = (signal_strength * 100) / (MAX_DBM_VALUE - MIN_DBM_VALUE); break; case SIGNAL_TYPE_RAW_RSSI: percent = (signal_strength * 100) / MAX_RAW_RSSI_VALUE; break; default: printf( "Warning: unrecognized signal type value: %d\n", signal_type ); } if( percent < 1 ) percent = 1; if( percent > 100 ) percent = 100; return percent;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -