FreeCalypso > hg > themwi-system-sw
view utils/tcpserv-dump.c @ 275:def9f6e4f49e default tip
doc/Use-outside-USA: Fake-NANP-numbers article is here
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 27 Nov 2023 21:49:19 -0800 |
parents | 9f6a148ceb25 |
children |
line wrap: on
line source
/* * This debug utility binds to a TCP port specified on the command line, * accepts incoming TCP connections and reads any bytes sent by a client * on an opened connection - but never sends anything back. A log file * is written, recording all received connections and bytes. */ #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <time.h> #include <unistd.h> #define MAXCONN 10 static struct in_addr bind_ip; static int tcp_port; static int listener, nconn, conns[MAXCONN], max_fd; static FILE *logf; static struct timeval curtime; static char fmt_time[32]; static void format_time() { struct tm *tm; tm = gmtime(&curtime.tv_sec); sprintf(fmt_time, "%d-%02d-%02dT%02d:%02d:%02dZ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } static void handle_accept(newfd, sin) struct sockaddr_in *sin; { fprintf(logf, "\n%s Accept conn from %s:%u fd %d\n", fmt_time, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), newfd); if (nconn < MAXCONN) { conns[nconn] = newfd; nconn++; if (newfd > max_fd) max_fd = newfd; } else { fprintf(logf, "MAXCONN exceeded, closing new fd\n"); close(newfd); } } static int handle_conn_fd(fd) { u_char buf[512]; int cc, off, chunk, i, c; cc = read(fd, buf, sizeof buf); fprintf(logf, "\n%s fd %d read %d\n", fmt_time, fd, cc); if (cc <= 0) { fprintf(logf, "closing fd\n"); return(1); } for (off = 0; off < cc; off += chunk) { fprintf(logf, "%04X: ", off); chunk = cc - off; if (chunk > 16) chunk = 16; for (i = 0; i < 16; i++) { if (i < chunk) fprintf(logf, "%02X ", buf[off + i]); else fputs(" ", logf); if (i == 7 || i == 15) putc(' ', logf); } for (i = 0; i < chunk; i++) { c = buf[off + i]; if (c < ' ' || c > '~') c = '.'; putc(c, logf); } putc('\n', logf); } return(0); } main(argc, argv) char **argv; { int rc, i; struct sockaddr_in sin; socklen_t addrlen; fd_set fds; if (argc != 4) { fprintf(stderr, "usage: %s bind-ip port logfile\n", argv[0]); exit(1); } bind_ip.s_addr = inet_addr(argv[1]); if (bind_ip.s_addr == INADDR_NONE) { fprintf(stderr, "error: invalid IP address argument \"%s\"\n", argv[1]); exit(1); } tcp_port = atoi(argv[2]); listener = socket(AF_INET, SOCK_STREAM, 0); if (listener < 0) { perror("socket"); exit(1); } sin.sin_family = AF_INET; sin.sin_addr = bind_ip; sin.sin_port = htons(tcp_port); rc = bind(listener, (struct sockaddr *) &sin, sizeof sin); if (rc < 0) { perror("bind"); exit(1); } logf = fopen(argv[3], "a"); if (!logf) { perror(argv[3]); exit(1); } rc = listen(listener, 5); if (rc < 0) { perror("listen"); exit(1); } gettimeofday(&curtime, 0); format_time(); fprintf(logf, "\n%s Test server started\n", fmt_time); fflush(logf); nconn = 0; max_fd = listener; for (;;) { FD_ZERO(&fds); FD_SET(listener, &fds); for (i = 0; i < nconn; i++) FD_SET(conns[i], &fds); rc = select(max_fd+1, &fds, 0, 0, 0); if (rc < 0) { if (errno == EINTR) continue; perror("select"); exit(1); } gettimeofday(&curtime, 0); format_time(); for (i = 0; i < nconn; ) { if (!FD_ISSET(conns[i], &fds)) { i++; continue; } if (handle_conn_fd(conns[i])) { close(conns[i]); nconn--; conns[i] = conns[nconn]; } else i++; } if (FD_ISSET(listener, &fds)) { addrlen = sizeof(struct sockaddr_in); rc = accept(listener, (struct sockaddr *) &sin, &addrlen); if (rc >= 0) handle_accept(rc, &sin); else fprintf(logf, "\n%s accept syscall error!\n", fmt_time); } fflush(logf); } }