//------------------------------------------------------------------- // multplex.cpp // // This program illustrates use of the 'select()' function for // efficiently performing multiplexed input from two devices. // // programmer: ALLAN CRUSE // written on: 23 APR 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #include // for tcgetattr(), tcsetattr() void handle_nic_input( int ); // prototypes our response to nic void handle_kbd_input( int ); // prototypes our response to kbd char devname[] = "/dev/nic"; // name of the device special file int done = 0; // flag used for loop-termination int main( void ) { // open the device-file for our network interface int nic = open( devname, O_RDWR ); if ( nic < 0 ) { perror( devname ); exit(1); } // preserve terminal settings and setup noncanonical input int kbd = STDIN_FILENO; struct termios orig_term; tcgetattr( kbd, &orig_term ); struct termios work_term = orig_term; work_term.c_lflag &= ~(ICANON | ECHO); work_term.c_cc[ VMIN ] = 1; // one character at a time work_term.c_cc[ VTIME ] = 0; // with no console timeout tcsetattr( kbd, TCSAFLUSH, &work_term ); // main program-loop performs the multiplexed device-input int maxfd = 1 + (( kbd < nic ) ? nic : kbd ); do { fd_set readset; FD_ZERO( &readset ); FD_SET( kbd, &readset ); FD_SET( nic, &readset ); if ( select( maxfd, &readset, NULL, NULL, NULL ) < 0 ) break; if ( FD_ISSET( kbd, &readset ) ) handle_kbd_input( kbd ); if ( FD_ISSET( nic, &readset ) ) handle_nic_input( nic ); } while ( !done ); // restore the original terminal-control settings tcsetattr( kbd, TCSAFLUSH, &orig_term ); printf( "\n" ); } void handle_kbd_input( int kbd ) { char inch[ 8 ] = {0}; int nbytes = read( kbd, inch, sizeof( inch ) ); if ( *(int*)inch == '\e' ) done = 1; else write( STDOUT_FILENO, &inch, nbytes ); } void handle_nic_input( int nic ) { unsigned char packet[ 64 ] = {0}; int nbytes = read( nic, packet, sizeof( packet ) ); if ( nbytes > 0 ) { printf( "\n" ); for (int i = 0; i < nbytes; i += 16) { printf( "\n%04X: ", i ); for (int j = 0; j < 16; j++) { if ( i+j < nbytes ) printf( "%02X ", packet[i+j] ); else printf( " " ); } for (int j = 0; j < 16; j++) { char ch = ' '; if ( i+j < nbytes ) ch = packet[ i+j ]; if (( ch < 0x20 )||( ch > 0x7E )) ch = '.'; printf( "%c", ch ); } } printf( "\n" ); } }