//------------------------------------------------------------------- // arpquery.cpp // // This application opens the '/dev/nic' device-file in order // to transmit an ARP request-packet and receive any replies. // It expects our 'rxplustx.c' device-driver to be installed. // // programmer: ALLAN CRUSE // written on: 20 APR 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for write(), read() #include // for memset(), memcpy(), memcmp() #include // for kill() #include // for gethostbyname() #include // for ioctl() #define GET_HWADDR 0 #define BUF_SIZE 64 char devname[] = "/dev/nic"; // name of the device special file int done = 0; void upon_signal( int sugnum ) { done = 1; } int main( int argc, char **argv ) { // open the device-file int fd = open( devname, O_RDWR ); if ( fd < 0 ) { perror( devname ); exit(1); } // get the network controller's hardware address unsigned char netaddr[ 10 ]; if ( ioctl( fd, GET_HWADDR, netaddr ) ) { perror( "ioctl" ); exit(1); } // get the workstation's hostname and IP-address char hostname[ 64 ] = {0}, hostaddr[ 16 ] = {0}; gethostname( hostname, 64 ); struct hostent *hostinfo = gethostbyname( hostname ); if ( !hostinfo ) { perror( "gethostbyname" ); exit(1); } // append station's IP-address to its hardware address memcpy( netaddr+6, hostinfo->h_addr_list[0], 4 ); // show the station's hostname and network addresses printf( "\n\tstation-hostname: %s ", hostname ); printf( "\n\tprotocol-address: " ); for (int i = 0; i < 4; i++) { char ch = ( i < 3 ) ? '.' : ' '; printf( "%d%c", netaddr[ 6+i ], ch ); } printf( "\n\thardware-address: " ); for (int i = 0; i < 6; i++) { char ch = ( i < 5 ) ? ':' : ' '; printf( "%02X%c", netaddr[ i ], ch ); } printf( "\n\n" ); fflush( stdout ); // fork a child-process to transmit ARP requests int pid = fork(); if ( pid == 0 ) { char message[ BUF_SIZE ] = {0}; char typelen[2] = { 0x08, 0x06 }; char htype[2] = { 0x00, 0x01 }; char ptype[2] = { 0x08, 0x00 }; char hlen[1] = { 0x06 }, plen[1] = { 0x04 }; char arpq[2] = { 0x00, 0x01 }; char askaddr[ 10 ] = { 0 }; // initialize the 'askaddr[]' array memcpy( askaddr+6, netaddr+6, 4 ); // setup the ethernet packet-header memset( message+0, 0xFF, 6 ); // dest'n-address memcpy( message+6, netaddr, 6 ); // source-address memcpy( message+12, typelen, 2 ); // type/length // setup the ARP packet-contents memcpy( message+14, htype, 2 ); // hardware-type memcpy( message+16, ptype, 2 ); // protocol-type memcpy( message+18, hlen, 1 ); // hw address-len memcpy( message+19, plen, 1 ); // IP address-len memcpy( message+20, arpq, 2 ); // ARP-request memcpy( message+22, netaddr, 10 ); // source net-addr memcpy( message+32, askaddr, 10 ); // dest'n IP-addr for (int n = 1; n < 255; n++) { message[41] = n; // adjust IP-dest'n // transmit the ARP request int nbytes = write( fd, message, BUF_SIZE ); if ( nbytes < 0 ) { perror( "write" ); exit(1); } for (int i = 0; i < 42; i++) { if ( ( i % 14 ) == 0 ) printf( "\n" ); printf( "%02X ", (unsigned char)message[i] ); } printf( "\n" ); fflush( stdout ); } sleep( 1 ); kill( getppid(), SIGINT ); exit( 0 ); } // parent-process receives the ARP responses char reply[ BUF_SIZE ] = {0}; signal( SIGINT, upon_signal ); while ( !done ) { int nbytes = read( fd, reply, BUF_SIZE ); if ( nbytes < 0 ) { perror( "read" ); exit(1); } unsigned short *wp = (unsigned short*)reply; if (( wp[6] == 0x0608 )&&( wp[10] == 0x0200 ) &&( memcmp( reply+38, netaddr+6, 4 ) == 0 )) { for (int i = 0; i < 42; i++) { if ( ( i % 14 ) == 0 ) printf( "\n\t" ); printf( "%02X ", (unsigned char)reply[i] ); } printf( "\n\n" ); fflush( stdout ); } } printf( "\nFinished\n\n" ); }