comparison utils/tcpserv-dump.c @ 215:67289fac8a44

utils: new program tcpserv-dump
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 24 Jul 2023 21:49:09 -0800
parents utils/sip-udp-dump.c@5995660dcbac
children 6aa2cd650943
comparison
equal deleted inserted replaced
214:10a4b0b0a239 215:67289fac8a44
1 /*
2 * This debug utility binds to a TCP port specified on the command line,
3 * accepts incoming TCP connections and reads any bytes sent by a client
4 * on an opened connection - but never sends anything back. A log file
5 * is written, recording all received connections and bytes.
6 */
7
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/time.h>
11 #include <sys/errno.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <strings.h>
18 #include <time.h>
19 #include <unistd.h>
20
21 #define MAXCONN 10
22
23 static int tcp_port;
24 static int listener, nconn, conns[MAXCONN], max_fd;
25 static FILE *logf;
26 static struct timeval curtime;
27 static char fmt_time[32];
28
29 static void
30 format_time()
31 {
32 struct tm *tm;
33
34 tm = gmtime(&curtime.tv_sec);
35 sprintf(fmt_time, "%d-%02d-%02dT%02d:%02d:%02dZ",
36 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
37 tm->tm_hour, tm->tm_min, tm->tm_sec);
38 }
39
40 static void
41 handle_accept(newfd, sin)
42 struct sockaddr_in *sin;
43 {
44 fprintf(logf, "\n%s Accept conn from %s:%u fd %d\n", fmt_time,
45 inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), newfd);
46 if (nconn < MAXCONN) {
47 conns[nconn] = newfd;
48 nconn++;
49 if (newfd > max_fd)
50 max_fd = newfd;
51 } else {
52 fprintf(logf, "MAXCONN exceeded, closing new fd\n");
53 close(newfd);
54 }
55 }
56
57 static int
58 handle_conn_fd(fd)
59 {
60 u_char buf[512];
61 int cc, off, chunk, i, c;
62
63 cc = read(fd, buf, sizeof buf);
64 fprintf(logf, "\n%s fd %d read %d\n", fmt_time, fd, cc);
65 if (cc <= 0) {
66 fprintf(logf, "closing fd\n");
67 return(1);
68 }
69 for (off = 0; off < cc; off += chunk) {
70 fprintf(logf, "%04X: ", off);
71 chunk = cc - off;
72 if (chunk > 16)
73 chunk = 16;
74 for (i = 0; i < 16; i++) {
75 if (i < chunk)
76 fprintf(logf, "%02X ", buf[off + i]);
77 else
78 fputs(" ", logf);
79 if (i == 7 || i == 15)
80 putc(' ', logf);
81 }
82 for (i = 0; i < chunk; i++) {
83 c = buf[off + i];
84 if (c < ' ' || c > '~')
85 c = '.';
86 putc(c, logf);
87 }
88 putc('\n', logf);
89 }
90 return(0);
91 }
92
93 main(argc, argv)
94 char **argv;
95 {
96 int max_fd, rc, i;
97 struct sockaddr_in sin;
98 socklen_t addrlen;
99 fd_set fds;
100
101 if (argc != 3) {
102 fprintf(stderr, "usage: %s port logfile\n", argv[0]);
103 exit(1);
104 }
105 tcp_port = atoi(argv[1]);
106 listener = socket(AF_INET, SOCK_STREAM, 0);
107 if (listener < 0) {
108 perror("socket");
109 exit(1);
110 }
111 sin.sin_family = AF_INET;
112 sin.sin_addr.s_addr = INADDR_ANY;
113 sin.sin_port = htons(tcp_port);
114 rc = bind(listener, (struct sockaddr *) &sin, sizeof sin);
115 if (rc < 0) {
116 perror("bind");
117 exit(1);
118 }
119 logf = fopen(argv[2], "a");
120 if (!logf) {
121 perror(argv[2]);
122 exit(1);
123 }
124 rc = listen(listener, 5);
125 if (rc < 0) {
126 perror("listen");
127 exit(1);
128 }
129 gettimeofday(&curtime, 0);
130 format_time();
131 fprintf(logf, "\n%s Test server started\n", fmt_time);
132 fflush(logf);
133 nconn = 0;
134 max_fd = listener;
135 for (;;) {
136 FD_ZERO(&fds);
137 FD_SET(listener, &fds);
138 for (i = 0; i < nconn; i++)
139 FD_SET(conns[i], &fds);
140 rc = select(max_fd+1, &fds, 0, 0, 0);
141 if (rc < 0) {
142 if (errno == EINTR)
143 continue;
144 perror("select");
145 exit(1);
146 }
147 gettimeofday(&curtime, 0);
148 format_time();
149 for (i = 0; i < nconn; ) {
150 if (!FD_ISSET(conns[i], &fds)) {
151 i++;
152 continue;
153 }
154 if (handle_conn_fd(conns[i])) {
155 close(conns[i]);
156 nconn--;
157 conns[i] = conns[nconn];
158 } else
159 i++;
160 }
161 if (FD_ISSET(listener, &fds)) {
162 addrlen = sizeof(struct sockaddr_in);
163 rc = accept(listener, (struct sockaddr *) &sin,
164 &addrlen);
165 if (rc >= 0)
166 handle_accept(rc, &sin);
167 else
168 fprintf(logf, "\n%s accept syscall error!\n",
169 fmt_time);
170 }
171 fflush(logf);
172 }
173 }