home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <errno.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <sgtty.h>
- #include <signal.h>
- #include <time.h>
-
- /*
- * tcpdialer - talk to a switch and remote dialer.
- *
- * usage: tcpdialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] [ -m max_tries ] -call host | -answer
- *
- * ARGUMENTS
- * -e escape_char Change escape character, enter as numeric value of the
- * character, use '\01' to set it to CNTRL-A
- * -l logfile Log data transfer to logfile.out and logfile.in.
- * -s Generate I/O stats when done.
- * -lp port Local port number to use.
- * -rp port Port number to use when on remote host.
- * -m max_tries Maximum number of connection attempts.
- * -call host Remote host to call.
- * -answer Answer any callers.
- *
- * Terminate using by typing ^C^C^C (three control-Cs).
- */
-
- static char* sccsid = "@(#)tcpdialer.c 1.7 10/29/93";
-
- #define MOUTHPIECE 0
- #define MAXPKTSIZE 1024
- #define ON 1
- #define OFF 0
- #define CTRLC '\003'
-
- FILE* outputlogf = NULL;
- FILE* inputlogf = NULL;
- struct sockaddr_in datagram;
- struct sgttyb saved_tty;
- time_t start_time = 0;
- char* program;
- char* remotehost = NULL;
- char* logfile = NULL;
- char packet[MAXPKTSIZE];
- char escape_char = CTRLC;
- short remoteport = 6123;
- short localport = 6123;
- short statistics = 0;
- short answermode = 0;
- short max_tries = 30;
- int pktcount = 0;
- int minpktsize = MAXPKTSIZE + 1;
- int maxpktsize = 0;
- int totalsize = 0;
- int sock;
-
- void terminate();
- void sig_child_handler();
-
- main(argc, argv)
- int argc;
- char** argv;
- {
-
- program = *argv;
-
- for (argc--, argv++; argc; argc--, argv++) {
- if (!strcmp(*argv, "-rp")) {
- remoteport = atoi(*(argv+1));
- argc--;
- argv++;
- }
- else if (!strcmp(*argv, "-lp")) {
- localport = atoi(*(argv+1));
- argc--;
- argv++;
- }
- else if (!strcmp(*argv, "-e")) {
- argv++;
- argc--;
- escape_char = atoi(*argv) && 0xff;
- fprintf(stderr, "escape char set to %d\n",escape_char);
- }
- else if (!strcmp(*argv, "-l")) {
- logfile = *(argv+1);
- argv++;
- argc--;
- }
- else if (!strcmp(*argv, "-s")) {
- statistics = 1;
- }
- else if (!strcmp(*argv, "-m")) {
- max_tries = atoi(*(argv+1));
- argc--;
- argv++;
- }
- else if (!strcmp(*argv, "-call")) {
- remotehost = *++argv;
- argc--;
- }
- else if (!strcmp(*argv, "-answer")) {
- answermode = 1;
- }
- else {
- fprintf(stderr, "usage: dialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] [ -m max_tries ] -call host | -answer \n");
- exit(1);
- }
- }
-
- /* verify proper mode */
- if ( remotehost && answermode ) {
- fprintf(stderr, "usage: dialer [ -s ] [ -rp port ] [ -lp port ] [ -m max_tries ] -call host | -answer \n");
- exit(1);
- }
- if ( !remotehost && !answermode ) {
- fprintf(stderr, "usage: dialer [ -s ] [ -rp port ] [ -lp port ] [ -m max_tries ] -call host | -answer \n");
- exit(1);
- }
-
- init_socket();
-
- save_tty_settings();
- raw();
- echo(OFF);
-
- /* the following never return */
- if (make_handset() == MOUTHPIECE) {
- signal(SIGTERM, terminate);
- do_mouthpiece();
- }
- else {
- /* when mouthpiece dies, we should too */
- signal(SIGCHLD, sig_child_handler);
-
- do_earpiece();
- }
-
- exit(0);
- }
-
- /* this socket will be used for both sending and receiving */
- init_socket() {
-
- void open_sock();
- struct sockaddr_in name;
- struct sockaddr_in saddr;
- struct hostent* hp;
- int msgsock;
- int errcode;
- int tries = 0;
- int len;
-
- open_sock();
-
- /* bind it */
- if (answermode) {
- name.sin_family = AF_INET;
- name.sin_addr.s_addr = INADDR_ANY;
- name.sin_port = htons(localport);
- if (bind(sock, (struct sockaddr*)&name, sizeof name) < 0) {
- perror("binding datagram socket");
- exit(2);
- }
-
- printf("Waiting for call...");
- fflush(stdout);
- listen(sock, 2);
- msgsock = accept(sock, (struct sockaddr*)0, (int*)0);
- if (msgsock == -1) {
- perror("accepting connection from remote host");
- exit(2);
- }
- len = sizeof(saddr);
- if (getpeername(msgsock, &saddr, &len) == 0) {
- printf("\007answered call from %s\n",inet_ntoa(saddr.sin_addr));
- }
- else {
- printf("\007answered call\n");
- }
- close(sock);
- sock = msgsock;
- }
- else {
- name.sin_family = AF_INET;
- hp = gethostbyname(remotehost);
- if (hp == 0) {
- fprintf(stderr, "%s: unknown host\n", remotehost);
- exit(2);
- }
- bcopy((char*)hp->h_addr, (char*)&name.sin_addr,hp->h_length);
- name.sin_port = htons(remoteport);
-
- /* try to make the connection */
- while (1) {
- printf("Ringing %s...", remotehost);
- fflush(stdout);
- errcode = connect(sock, (struct sockaddr*)&name,
- sizeof name);
- if (errcode == -1) {
- if (errno == ECONNREFUSED || errno == EINTR) {
- sleep(5);
- if (++tries < max_tries) {
- printf("\n");
- close(sock);
- open_sock();
- continue;
- }
- else {
- /* too many retries */
- perror("connect");
- exit(2);
- }
- }
- else {
- /* error during connect */
- perror("connect");
- exit(2);
- }
- }
- else {
- printf("\007connected\n");
- break;
- }
- }
- }
- }
-
- void open_sock() {
-
- int on = 1;
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("opening datagram socket");
- exit(2);
- }
-
- #ifdef SO_KEEPALIVE
- /* use keepalives to force us to die when the remote dies */
- if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
- perror("cannot set sock option");
- }
- #endif
- }
-
- /* create a reader process */
- make_handset() {
-
- /*
- * The reader process reads the tty and sends the data
- * to the remote host.
- */
-
- int pid = fork();
- if (pid < 0) {
- perror("forking reader process");
- exit(3);
- }
-
- return pid;
- }
-
- do_mouthpiece() {
-
- struct timeval tv;
- int bytecount;
- int endsequence = 0;
- char logname[1024];
-
- /* logfile prep */
- if (logfile) {
- strcpy(logname, logfile);
- strcat(logname, ".out");
- outputlogf = fopen(logname, "w");
- }
-
- /* record starting time */
- time(&start_time);
-
- while (1) {
- /* keep delay between read/write to a minimum! */
- bytecount = read(0, packet, 1024);
- if (bytecount) {
- if (write(sock, packet, bytecount) < 0)
- perror("sending datagram message");
-
- /* log data */
- if (outputlogf) {
- gettimeofday(&tv, NULL);
- fwrite(&tv, sizeof(tv), 1, outputlogf);
- fwrite(&bytecount, sizeof(bytecount), 1, outputlogf);
- fwrite(packet, sizeof(char), bytecount, outputlogf);
- }
-
- if (bytecount == 1 && (packet[0]&0177) == escape_char) {
- if (++endsequence == 3)
- terminate();
- }
- else
- endsequence = 0;
-
- /* statistics generation */
- pktcount++;
- totalsize += bytecount;
- if (bytecount < minpktsize) minpktsize = bytecount;
- else if (bytecount > maxpktsize) maxpktsize = bytecount;
- }
- }
- }
-
- do_earpiece() {
-
- struct timeval tv;
- int bytecount;
- char logname[1024];
-
- /* logfile prep */
- if (logfile) {
- strcpy(logname, logfile);
- strcat(logname, ".in");
- inputlogf = fopen(logname, "w");
- }
-
- while (1) {
- bytecount = read(sock, packet, 1024);
- if (bytecount > 0) {
- write(1, packet, bytecount);
-
- /* log data */
- if (inputlogf) {
- gettimeofday(&tv, NULL);
- fwrite(&tv, sizeof(tv), 1, inputlogf);
- fwrite(&bytecount, sizeof(bytecount), 1, inputlogf);
- fwrite(packet, sizeof(char), bytecount, inputlogf);
- }
- }
- }
- }
-
- /* save the original tty settings */
- save_tty_settings() {
- gtty(0, &saved_tty);
- }
-
- /* restore the original tty settings */
- restore_tty_settings() {
- stty(0, &saved_tty);
- }
-
- /* place the terminal in raw mode */
- raw() {
- struct sgttyb tty;
-
- gtty(0, &tty);
- tty.sg_flags |= RAW;
- stty(0, &tty);
- }
-
- /* place the terminal in cooked mode */
- cooked() {
- struct sgttyb tty;
-
- gtty(0, &tty);
- tty.sg_flags &= ~RAW;
- stty(0, &tty);
- }
-
- echo(on)
- int on;
- {
-
- struct sgttyb tty;
-
- gtty(0, &tty);
- if (on) {
- tty.sg_flags |= ECHO;
- }
- else
- tty.sg_flags &= ~ECHO;
-
- stty(0, &tty);
- }
-
- void sig_child_handler() {
-
- restore_tty_settings();
-
- if (outputlogf)
- fclose(outputlogf);
- if (inputlogf)
- fclose(inputlogf);
-
- exit(0);
- }
-
- void terminate() {
-
- time_t time_diff = time(0) - start_time;
-
- if (outputlogf)
- fclose(outputlogf);
- if (inputlogf)
- fclose(inputlogf);
-
- /* report statistics */
- if (statistics) {
- printf("%d packets, %d bytes, %d/%d/%d min/avg/max pkt size\r\n",
- pktcount, totalsize, minpktsize, totalsize/pktcount,
- maxpktsize);
- if (time_diff)
- printf("%d seconds, %g pkt/s, %d b/s\r\n",
- time_diff, (float)pktcount / (float)time_diff,
- totalsize/time_diff);
- }
-
- exit(0);
- }
-