//------------------------------------------------------------------- // tryarp.cpp (A revision of our 'nicstudy.cpp' deno) // // This program (which requires our 'user8139.c' device-driver) // modifies the 'nicstudy.cpp' demo to transmit an ARP-request. // // programmer: ALLAN CRUSE // written on: 11 APR 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), lseek() #include // for mmap(), munmap() #include // for memset(), memcpy(), strncpy() char nicname[] = "/dev/nic"; // name of the device special file void show_nic_registers( void *vm ) { // display the contents of io-memory in hexadecimal format printf( "\n\nRealTek 8139 Registers mapped at %p \n", vm ); unsigned long *lp = (unsigned long *)vm; for (int i = 0; i < 64; i++) { if ( ( i % 8 ) == 0 ) printf( "\n%02X: ", i*4 ); printf( "%08lX ", lp[ i ] ); } printf( "\n" ); } int main( int argc, char **argv ) { // open the device-file int fd = open( nicname, O_RDWR ); if ( fd < 0 ) { perror( nicname ); exit(1); } // map the device's io-memory to user-space int prot = PROT_READ | PROT_WRITE; int flag = MAP_SHARED; int size = 0x1000; int base = 0; void *vm = mmap( NULL, size, prot, flag, fd, base ); if ( vm == MAP_FAILED ) { perror( "mmap" ); exit(1); } // display the contents of io-memory in hexadecimal format show_nic_registers( vm ); // reset the network controller int io = (int)vm; unsigned char *RTCommand = (unsigned char *)(io+0x37); unsigned long *TxStatus0 = (unsigned long *)(io+0x10); unsigned long *Tx_Config = (unsigned long *)(io+0x40); *RTCommand = 0x10; // initiate the NIC reset while ( *RTCommand & 0x10 ); // await reset completion // construct an Address Resolution Protocol request-packet char packet[ 64 ] = {0}; memset( packet+0, 0xFF, 6 ); // broadcast address // packet type (0x0806 = Address Resolution Protocol) packet[12] = 0x08; packet[13] = 0x06; // HTYPE (Hardware Type: 0x0001 = Ethernet) packet[14] = 0x00; packet[15] = 0x01; // PTYPE (Protocol Type: 0x0800 = IP) packet[16] = 0x08; packet[17] = 0x00; // HLEN (Hardware Length) packet[18] = 0x06; // PLEN (Protocol Length) packet[19] = 0x04; // OPER (ARP Request) packet[20] = 0x00; packet[21] = 0x01; // SHA (Source Hardware Address: lectern02.cs.usfca.edu) packet[22] = 0x00; packet[23] = 0xE0; packet[24] = 0x18; packet[25] = 0x8B; packet[26] = 0x2C; packet[27] = 0x9E; // SPA (Source Protocol Address: lectern02.cs.usfca.edu) packet[28] = 138; packet[29] = 202; packet[30] = 171; packet[31] = 59; // THA (Target Hardware Address) memset( packet+32, 0x00, 6 ); // broadcast address // TPA (Target Protocol Address: hrn23501.cs.usfca.edu) packet[38] = 192; packet[39] = 168; packet[40] = 171; packet[41] = 1; memcpy( packet+6, packet+22, 6 ); // source address // place our network packet into the kernel buffer lseek( fd, 0, SEEK_SET ); // point to TxBuffer0 int nbytes = write( fd, packet, sizeof(packet) ); // then ask the RTL-8139 to transmit that packet *RTCommand = 0x04; // enable TX *Tx_Config = 0; // configure TX *TxStatus0 = 64; // transmit TxBuffer0 // poll the 'OWN' bit in the Transmit Descriptor Status while ( (*TxStatus0 & 0xC000) == 0 ); if ( (*TxStatus0 & 0xE000) == 0xA000 ) printf( "Packet was successfully transmitted\n" ); else printf( "Packet encountered transmit failure\n" ); }