/*+-------------------------------------------------------------------+*/ /*| |*/ /*| PROGRAM NAME: nbttcp28 |*/ /*| ------------- |*/ /*| Test-Client for Unix / Linux / BSD using xti. |*/ /*| sends data on special port DEF_TCPIP_PORT |*/ /*| KB 01.11.04 |*/ /*| |*/ /*| COPYRIGHT: |*/ /*| ---------- |*/ /*| Copyright (C) HOB 2004 |*/ /*| |*/ /*| LICENCE AGREEMENT: |*/ /*| ---------- |*/ /*| Licence agreement, HOB GmbH & Co. KG |*/ /*| |*/ /*| This software is provided "as-is", without any express or implied |*/ /*| warranty. In no event will the authors be held liable for any |*/ /*| damages arising from the use of this software. |*/ /*| |*/ /*| Permission is granted to anyone to use this software for any |*/ /*| purpose, including commercial applications, and to alter it and |*/ /*| redistribute it freely, subject to the following restrictions: |*/ /*| |*/ /*| 1. The origin of this software must not be misrepresented; you |*/ /*| not claim that you wrote the original software. If you use |*/ /*| this software in a product, an acknowledgment in the product |*/ /*| documentation would be appreciated but is not required. |*/ /*| 2. Altered source versions must be plainly marked as such, and |*/ /*| must not be misrepresented as being the original software. |*/ /*| 3. This notice may not be removed or altered from any source |*/ /*| distribution. |*/ /*| |*/ /*| EXPECTED INPUT: |*/ /*| --------------- |*/ /*| Parameter 1 is IP-address of server |*/ /*| Parameter 2 is amount of data to send |*/ /*| Parameter 3 is function requested |*/ /*| |*/ /*| EXPECTED OUTPUT: |*/ /*| ---------------- |*/ /*| displays time required on console |*/ /*| |*/ /*+-------------------------------------------------------------------+*/ /*+-------------------------------------------------------------------+*/ /*| System and library header files. |*/ /*+-------------------------------------------------------------------+*/ #ifdef HL_LINUX #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef HL_LINUX #include #endif #include #ifdef HL_OPENUNIX #include #endif #include #include #ifdef HL_LINUX #include #include #endif #include #include #include #ifndef SOLARIS_INC #define SOLARIS_INC #define SOLARIS #include #include #define TRUE 1 #define FALSE 0 #define BOOL int #endif /* end of HUNX01.h */ #define STACK_TCPR 8192UL /* stack s for TCP/IP rec */ #define DEF_TCPIP_PORT 4097 /* port for TCP/IP */ #define DEF_RECLEN 1536 /* length to send */ #define DEF_AMOUNT 4096 /* amount of data to send */ #define CHAR_CR 0X0D /* carriage-return */ #define CHAR_LF 0X0A /* line-feed */ #define TID DWORD #define HEV void * #define HQUEUE void * #define APIRET int #define HFILE int #define LONGLONG long long int #ifndef HL_AIX #define DEF_T_OPEN_TCP_IPV4 "/dev/tcp" /* device-name TCP IP V 4 */ #define DEF_T_OPEN_TCP_IPV6 "/dev/tcp6" /* device-name TCP IP V 6 */ #define DEF_T_OPEN_UDP "/dev/udp" /* device-name UDP */ #else #define DEF_T_OPEN_TCP_IPV4 "/dev/xti/tcp" /* device-name TCP */ #define DEF_T_OPEN_TCP_IPV6 "/dev/xti/tcp6" /* device-name TCP IP V 6 */ #define DEF_T_OPEN_UDP "/dev/xti/udp" /* device-name UDP */ #define INFTIM -1 /* value for IP */ #endif /*+-------------------------------------------------------------------+*/ /*| global used dsects = structures. |*/ /*+-------------------------------------------------------------------+*/ /*+-------------------------------------------------------------------+*/ /*| function call definitions |*/ /*+-------------------------------------------------------------------+*/ static unsigned long m_get_time( void ); /*+-------------------------------------------------------------------+*/ /*| Internal function prototypes. |*/ /*+-------------------------------------------------------------------+*/ /*+-------------------------------------------------------------------+*/ /*| Static global variables and local constants. |*/ /*+-------------------------------------------------------------------+*/ static LONGLONG ils_sendmax; /* amount to send */ static LONGLONG ils_countd; /* length sended */ static int ims_countr; /* count records */ static int ims_function; /* function requested */ static char *achs_send; /* data to send */ /*+-------------------------------------------------------------------+*/ /*| Main control procedure. |*/ /*+-------------------------------------------------------------------+*/ int main( int argc, char *argv[] ) { APIRET iml_rc_f; /* return code */ int iml1; int iml2; int iml3; LONGLONG ill1; /* work-area */ char *achl1; char *achl2; char *achl3; char *achl4; char *achl5; BOOL bol1; int iml_rc_sock; /* return code */ int iml_sock_client; /* socket for connection */ int iml_send; /* length sended */ int iml_time_sta; /* save for time started */ int iml_time_dif; /* difference time / elaps */ char chrl_work_1[64]; /* work-area */ char chrl_work_2[64]; /* work-area */ struct sockaddr_in dsl_soa_server; /* server address informat */ struct hostent *adsl_host_entry; struct t_call dsl_call_con; /* for connect */ t_info dsl_info_1; pollfd dsrl_poll[1]; /* for poll() */ FILE * dsl_hfi; /* input-file */ unsigned long int uml_read; /* bytes read */ long int iml_file_size; /* return File Size */ long int iml_file_pos; /* current position in file */ printf( "nbttcp28 started / Version 1.1 " __DATE__ "\n" ); if (argc < 2) { printf( "HOB nbttcp28 help\n\ parameter 1 = IP-address of server\n\ parameter 2 = amount of data\n\ parameter 3 = function requested\n\ function 0 = transfer file, parameter 4 is file-name\n\ function 1 = send prime numbers (not compressable)\n\ function 2 = send only zeroes (most compressable run-length)\n\ function 3 = send pattern TESTTEST (good compressable LZ)\n" ); return 1; } ils_sendmax = 0; if (argc >= 3) { achl1 = argv[2]; achl2 = achl1 + strlen( achl1 ); bol1 = FALSE; while (achl1 < achl2) { if (bol1 == FALSE) { if ((*achl1 >= '0') && (*achl1 <= '9')) { ils_sendmax *= 10; ils_sendmax += *achl1 - '0'; } else if ((*achl1 == 'G') || (*achl1 == 'g')) { ils_sendmax *= 1024 * 1024 * 1024; bol1 = TRUE; } else if ((*achl1 == 'M') || (*achl1 == 'm')) { ils_sendmax *= 1024 * 1024; bol1 = TRUE; } else if ((*achl1 == 'K') || (*achl1 == 'k')) { ils_sendmax *= 1024; bol1 = TRUE; } else { printf( "amount invalid character %c\n", *achl1 ); } } else { printf( "amount superflous characters %s\n", achl1 ); break; } achl1++; } } if (ils_sendmax <= 0) ils_sendmax = DEF_AMOUNT; ims_function = 2; if (argc >= 4) { ims_function = atoi( argv[3] ); } iml1 = 4; if (ims_function == 0) { iml1 = 5; if (argc < iml1) { printf( "too less parameters entered\n" ); return 1; } } if (argc > iml1) { printf( "superflous parameters entered\n" ); } memset( (char *) &dsl_soa_server, 0, sizeof(struct sockaddr_in) ); dsl_soa_server.sin_family = AF_INET; dsl_soa_server.sin_port = htons( DEF_TCPIP_PORT ); *((unsigned long int *) &(dsl_soa_server.sin_addr)) = inet_addr( argv[1] ); if (*((unsigned long int *) &(dsl_soa_server.sin_addr)) == 0XFFFFFFFF) { adsl_host_entry = gethostbyname( (char *) argv[1] ); if (adsl_host_entry == 0) { printf( "error gethostbyname %s\n", argv[1] ); return 1; } memcpy( (char *) &(dsl_soa_server.sin_addr), (*adsl_host_entry).h_addr, (*adsl_host_entry).h_length ); } if (*((unsigned long int *) &(dsl_soa_server.sin_addr)) == 0XFFFFFFFF) { printf( "no IP-address found. %s\n", argv[1] ); return 1; } memset( (char *) &dsl_call_con, 0, sizeof(t_call) ); dsl_call_con.addr.maxlen = sizeof(struct sockaddr_in); dsl_call_con.addr.len = sizeof(struct sockaddr_in); dsl_call_con.addr.buf = (char *) &dsl_soa_server; dsl_call_con.opt.maxlen = 0; dsl_call_con.opt.len = 0; dsl_call_con.udata.maxlen = 0; dsl_call_con.udata.len = 0; iml_sock_client = t_open( DEF_T_OPEN_TCP_IPV4, O_RDWR | O_NONBLOCK, &dsl_info_1 ); if (iml_sock_client < 0) { printf( "t_open socket client failed with t_errno=%d\n", t_errno ); return 1; } memset( dsrl_poll, 0, sizeof(dsrl_poll) ); dsrl_poll[0].fd = iml_sock_client; iml_rc_sock = t_bind( iml_sock_client, NULL, NULL ); if (iml_rc_sock < 0) { printf( "t_bind socket client failed with t_errno=%d\n", t_errno ); return 1; } iml_rc_sock = t_connect( iml_sock_client, &dsl_call_con, NULL ); if (iml_rc_sock < 0) { if (t_errno != TNODATA) { printf( "t_connect failed with t_errno=%d\n", t_errno ); iml_rc_sock = t_unbind( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_unbind failed with t_errno=%d\n", t_errno ); } iml_rc_sock = t_close( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_close failed with t_errno=%d\n", t_errno ); } return 1; } dsrl_poll[0].events = POLLIN; while (TRUE) { dsrl_poll[0].revents = 0; iml_rc_f = poll( dsrl_poll, 1, INFTIM ); if (dsrl_poll[0].revents & POLLIN) break; } iml_rc_sock = t_rcvconnect( iml_sock_client, &dsl_call_con ); if (iml_rc_sock < 0) { printf( "t_rcvconnect failed with t_errno=%d\n", t_errno ); if (t_errno == TLOOK) { iml_rc_sock = t_look( iml_sock_client ); achl1 = ""; if (iml_rc_sock == T_DISCONNECT) achl1 = " T_DISCONNECT"; printf( "t_rcvconnect() connect TLOOK - t_look=%d%s\n", iml_rc_sock, achl1 ); } iml_rc_sock = t_unbind( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_unbind failed with t_errno=%d\n", t_errno ); } iml_rc_sock = t_close( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_close failed with t_errno=%d\n", t_errno ); } return 1; } } achs_send = (char *) malloc( DEF_RECLEN ); /* get block to send */ switch (ims_function) { case 0: goto pfunc000; case 1: goto pfunc100; case 2: goto pfunc200; case 3: goto pfunc300; } printf( "invalid function requested %d\n", ims_function ); return 1; pfunc000: /* send a complete file */ /* read the complete file into storage. */ /* achl1 is start of file, achl2 is end of file */ dsl_hfi = fopen( argv[4], "rt" ); if (dsl_hfi == 0) { printf( "input fopen Error errno=%d\n", errno ); iml_rc_sock = t_unbind( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_unbind failed with t_errno=%d\n", t_errno ); } iml_rc_sock = t_close( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_close failed with t_errno=%d\n", t_errno ); } return 1; } iml_file_pos = ftell( (FILE *) dsl_hfi ); fseek( (FILE *) dsl_hfi, 0, SEEK_END ); iml_file_size = ftell( (FILE *) dsl_hfi ); fseek( (FILE *) dsl_hfi, iml_file_pos, SEEK_SET ); #define ALIAS_FILESIZE iml_file_size achl1 = (char *) malloc( ALIAS_FILESIZE ); achl2 = achl1 + ALIAS_FILESIZE; uml_read = fread( achl1, 1, ALIAS_FILESIZE, (FILE *) dsl_hfi ); if (uml_read != ALIAS_FILESIZE) { printf( "input fread Error: returned=%d errno=%d\n", uml_read, errno ); iml_rc_sock = t_unbind( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_unbind failed with t_errno=%d\n", t_errno ); } iml_rc_sock = t_close( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_close failed with t_errno=%d\n", t_errno ); } return 1; } fclose( (FILE *) dsl_hfi ); achl3 = achl1; /* start here */ ils_countd = ils_sendmax; /* amount to send */ ims_countr = 0; /* nothing sended */ iml_time_sta = m_get_time(); /* save time started */ pfunc020: /* send one block */ iml1 = DEF_RECLEN; /* length to send */ ils_countd -= DEF_RECLEN; /* after this block */ if (ils_countd < 0) { /* only part */ iml1 += ils_countd; ils_countd = 0; } achl4 = achl3; /* send from file */ achl3 += iml1; /* add length */ if ((achl2 - achl4) < iml1) { /* not complete */ achl3 = achl4; /* copy from here */ achl4 = achl5 = achs_send; /* start from here */ iml3 = iml1; /* how much to fill */ do { iml2 = achl2 - achl3; /* length in this block */ if (iml2) { memcpy( achl5, achl2, iml2 ); achl5 += iml2; iml3 -= iml2; } achl3 = achl1; /* start from beg. again */ iml2 = achl2 - achl3; /* length maximum */ if (iml2 > iml3) iml2 = iml3; memcpy( achl5, achl3, iml2 ); achl3 += iml2; achl5 += iml2; iml3 -= iml2; } while (iml3 > 0); } while (TRUE) { /* loop to send */ iml_send = t_snd( iml_sock_client, achl4, iml1, 0 ); if (iml_send == iml1) break; /* all send */ if (iml_send > 0) { /* a part send */ achl4 += iml_send; /* increment address */ iml1 -= iml_send; /* decrement length */ continue; /* send again */ } if (t_errno != TFLOW) { /* error send */ ils_countd += iml1; /* not yet sended */ printf( "error send iml_send=%d t_errno=%d\n", iml_send, t_errno ); // free( achl1 ); /* free storage with file */ goto pmtsend40; } dsrl_poll[0].events = POLLOUT; while (TRUE) { dsrl_poll[0].revents = 0; iml_rc_f = poll( dsrl_poll, 1, INFTIM ); if (dsrl_poll[0].revents & POLLOUT) break; } } ims_countr++; /* count block */ if (ils_countd > 0) goto pfunc020; /* continue sending */ // free( achl1 ); /* free storage with file */ goto pmtsend40; /* all done */ pfunc100: /* send prime numbers */ /* make a map of prime numbers */ achl1 = achs_send; achl2 = achl1 + DEF_RECLEN; iml1 = 1; iml2 = 0; do { if (iml2 == 0) { bol1 = TRUE; do { iml1 += 2; iml2 = 1; while (TRUE) { iml2 += 2; if ((iml2 * iml2) > iml1) { bol1 = FALSE; break; } if ((iml1 % iml2) == 0) break; } } while (bol1); iml2 = 256; iml3 = 0; } *achl1++ = iml3 % 256; iml3 += iml1; iml2--; } while (achl1 < achl2); ils_countd = ils_sendmax; /* amount to send */ ims_countr = 0; /* nothing sended */ iml_time_sta = m_get_time(); /* save time started */ pmtsend20: /* send one block */ iml1 = DEF_RECLEN; /* length to send */ ils_countd -= DEF_RECLEN; /* after this block */ if (ils_countd < 0) { /* only part */ iml1 += ils_countd; ils_countd = 0; } achl4 = achs_send; /* start sending this data */ while (TRUE) { /* loop to send */ iml_send = t_snd( iml_sock_client, achl4, iml1, 0 ); if (iml_send == iml1) break; /* all send */ if (iml_send > 0) { /* a part send */ achl4 += iml_send; /* increment address */ iml1 -= iml_send; /* decrement length */ continue; /* send again */ } if (t_errno != TFLOW) { /* error send */ ils_countd += iml1; /* not yet sended */ printf( "error send iml_send=%d t_errno=%d\n", iml_send, t_errno ); goto pmtsend40; } dsrl_poll[0].events = POLLOUT; while (TRUE) { dsrl_poll[0].revents = 0; iml_rc_f = poll( dsrl_poll, 1, INFTIM ); if (dsrl_poll[0].revents & POLLOUT) break; } } ims_countr++; /* count block */ if (ils_countd > 0) goto pmtsend20; /* continue sending */ goto pmtsend40; /* all done */ pfunc200: /* send only zeroes */ memset( achs_send, 0, DEF_RECLEN ); /* clear block to send */ ils_countd = ils_sendmax; /* amount to send */ ims_countr = 0; /* nothing sended */ iml_time_sta = m_get_time(); /* save time started */ pfunc220: /* send one block */ iml1 = DEF_RECLEN; /* length to send */ ils_countd -= DEF_RECLEN; /* after this block */ if (ils_countd < 0) { /* only part */ iml1 += ils_countd; ils_countd = 0; } achl4 = achs_send; /* start sending this data */ while (TRUE) { /* loop to send */ iml_send = t_snd( iml_sock_client, achl4, iml1, 0 ); if (iml_send == iml1) break; /* all send */ if (iml_send > 0) { /* a part send */ achl4 += iml_send; /* increment address */ iml1 -= iml_send; /* decrement length */ continue; /* send again */ } if (t_errno != TFLOW) { /* error send */ ils_countd += iml1; /* not yet sended */ printf( "error send iml_send=%d t_errno=%d\n", iml_send, t_errno ); goto pmtsend40; } dsrl_poll[0].events = POLLOUT; while (TRUE) { dsrl_poll[0].revents = 0; iml_rc_f = poll( dsrl_poll, 1, INFTIM ); if (dsrl_poll[0].revents & POLLOUT) break; } } ims_countr++; /* count block */ if (ils_countd > 0) goto pfunc220; /* continue sending */ goto pmtsend40; /* all done */ pfunc300: /* send TESTTEST */ ils_countd = ils_sendmax; /* amount to send */ ims_countr = 0; /* nothing sended */ achl1 = achl2 = "TESTTEST"; achl3 = achl2 + strlen( achl1 ); iml_time_sta = m_get_time(); /* save time started */ pfunc320: /* send one block */ iml1 = DEF_RECLEN; /* length to send */ ils_countd -= DEF_RECLEN; /* after this block */ if (ils_countd < 0) { /* only part */ iml1 += ils_countd; ils_countd = 0; } achl4 = achs_send; /* set start */ achl5 = achl4 + iml1; /* end of block */ do { if (achl2 == achl3) achl2 = achl1; iml2 = achl5 - achl4; iml3 = achl3 - achl2; if (iml2 > iml3) iml2 = iml3; memcpy( achl4, achl2, iml2 ); achl2 += iml2; achl4 += iml2; } while (achl4 < achl5); achl4 = achs_send; /* start sending this data */ while (TRUE) { /* loop to send */ iml_send = t_snd( iml_sock_client, achl4, iml1, 0 ); if (iml_send == iml1) break; /* all send */ if (iml_send > 0) { /* a part send */ achl4 += iml_send; /* increment address */ iml1 -= iml_send; /* decrement length */ continue; /* send again */ } if (t_errno != TFLOW) { /* error send */ ils_countd += iml1; /* not yet sended */ printf( "error send iml_send=%d t_errno=%d\n", iml_send, t_errno ); goto pmtsend40; } dsrl_poll[0].events = POLLOUT; while (TRUE) { dsrl_poll[0].revents = 0; iml_rc_f = poll( dsrl_poll, 1, INFTIM ); if (dsrl_poll[0].revents & POLLOUT) break; } } ims_countr++; /* count block */ if (ils_countd > 0) goto pfunc320; /* continue sending */ goto pmtsend40; /* all done */ pmtsend40: /* all data sended */ iml_time_dif = m_get_time() - iml_time_sta; /* get time elapsed */ ill1 = ils_sendmax - ils_countd; /* length sended */ achl2 = chrl_work_1 + sizeof(chrl_work_1) - 1; /* end of variable */ *achl2 = 0; iml1 = 3; do { if (iml1 == 0) { *(--achl2) = ','; iml1 = 3; } iml1--; achl2--; *achl2 = (ill1 % 10) + '0'; ill1 /= 10; } while (ill1); iml1 = iml_time_dif; if (iml1 <= 0) iml1 = 1; /* do not divide by zero */ ill1 = (ils_sendmax - ils_countd) * 8 * 1000 / iml1; /* speed bits/sec */ achl3 = chrl_work_2 + (sizeof(chrl_work_1) / 2); /* end of variable */ strcpy( achl3, " Bits per second" ); iml1 = 3; do { if (iml1 == 0) { *(--achl3) = ','; iml1 = 3; } iml1--; achl3--; *achl3 = (ill1 % 10) + '0'; ill1 /= 10; } while (ill1); printf( "socket %d - time elapsed: %d milliseconds\ - blocks: %d - data: %s - speed: %s\n", iml_sock_client, iml_time_dif, ims_countr, achl2, achl3 ); iml_rc_sock = t_close( iml_sock_client ); if (iml_rc_sock != 0 ) { printf( "t_close failed with t_errno=%d\n", t_errno ); } free( achs_send ); return 0; } /** * m_get_time() * calculating current time in milliseconds since midnight (00:00:00), January 1, 1970 * * return time in Milliseconds */ static unsigned long int m_get_time( void ) { struct timeval dsl_current; gettimeofday( &dsl_current, NULL ); return (dsl_current.tv_sec * 1000 + dsl_current.tv_usec / 1000 ); }