FreeCalypso > hg > themwi-system-sw
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 } |