root / slirp / misc.c @ 3a9d8549
History | View | Annotate | Download (9.6 kB)
1 | f0cbd3ec | bellard | /*
|
---|---|---|---|
2 | f0cbd3ec | bellard | * Copyright (c) 1995 Danny Gasparovski.
|
3 | 5fafdf24 | ths | *
|
4 | f0cbd3ec | bellard | * Please read the file COPYRIGHT for the
|
5 | f0cbd3ec | bellard | * terms and conditions of the copyright.
|
6 | f0cbd3ec | bellard | */
|
7 | f0cbd3ec | bellard | |
8 | f0cbd3ec | bellard | #include <slirp.h> |
9 | 6dbe553f | Jan Kiszka | #include <libslirp.h> |
10 | 6dbe553f | Jan Kiszka | |
11 | 6dbe553f | Jan Kiszka | #include "monitor.h" |
12 | f0cbd3ec | bellard | |
13 | 9f349498 | Jan Kiszka | #ifdef DEBUG
|
14 | 9f349498 | Jan Kiszka | int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
|
15 | 9f349498 | Jan Kiszka | #endif
|
16 | 9f349498 | Jan Kiszka | |
17 | f0cbd3ec | bellard | struct quehead {
|
18 | f0cbd3ec | bellard | struct quehead *qh_link;
|
19 | f0cbd3ec | bellard | struct quehead *qh_rlink;
|
20 | f0cbd3ec | bellard | }; |
21 | f0cbd3ec | bellard | |
22 | f0cbd3ec | bellard | inline void |
23 | 511d2b14 | blueswir1 | insque(void *a, void *b) |
24 | f0cbd3ec | bellard | { |
25 | f0cbd3ec | bellard | register struct quehead *element = (struct quehead *) a; |
26 | f0cbd3ec | bellard | register struct quehead *head = (struct quehead *) b; |
27 | f0cbd3ec | bellard | element->qh_link = head->qh_link; |
28 | f0cbd3ec | bellard | head->qh_link = (struct quehead *)element;
|
29 | f0cbd3ec | bellard | element->qh_rlink = (struct quehead *)head;
|
30 | f0cbd3ec | bellard | ((struct quehead *)(element->qh_link))->qh_rlink
|
31 | f0cbd3ec | bellard | = (struct quehead *)element;
|
32 | f0cbd3ec | bellard | } |
33 | f0cbd3ec | bellard | |
34 | f0cbd3ec | bellard | inline void |
35 | 511d2b14 | blueswir1 | remque(void *a)
|
36 | f0cbd3ec | bellard | { |
37 | f0cbd3ec | bellard | register struct quehead *element = (struct quehead *) a; |
38 | f0cbd3ec | bellard | ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
|
39 | f0cbd3ec | bellard | ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
|
40 | f0cbd3ec | bellard | element->qh_rlink = NULL;
|
41 | f0cbd3ec | bellard | } |
42 | f0cbd3ec | bellard | |
43 | a13a4126 | Jan Kiszka | int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, |
44 | a13a4126 | Jan Kiszka | struct in_addr addr, int port) |
45 | f0cbd3ec | bellard | { |
46 | f0cbd3ec | bellard | struct ex_list *tmp_ptr;
|
47 | 5fafdf24 | ths | |
48 | f0cbd3ec | bellard | /* First, check if the port is "bound" */
|
49 | f0cbd3ec | bellard | for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
|
50 | a13a4126 | Jan Kiszka | if (port == tmp_ptr->ex_fport &&
|
51 | a13a4126 | Jan Kiszka | addr.s_addr == tmp_ptr->ex_addr.s_addr) |
52 | a13a4126 | Jan Kiszka | return -1; |
53 | f0cbd3ec | bellard | } |
54 | 5fafdf24 | ths | |
55 | f0cbd3ec | bellard | tmp_ptr = *ex_ptr; |
56 | f0cbd3ec | bellard | *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); |
57 | f0cbd3ec | bellard | (*ex_ptr)->ex_fport = port; |
58 | f0cbd3ec | bellard | (*ex_ptr)->ex_addr = addr; |
59 | f0cbd3ec | bellard | (*ex_ptr)->ex_pty = do_pty; |
60 | e1c5a2b3 | aliguori | (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
|
61 | f0cbd3ec | bellard | (*ex_ptr)->ex_next = tmp_ptr; |
62 | f0cbd3ec | bellard | return 0; |
63 | f0cbd3ec | bellard | } |
64 | f0cbd3ec | bellard | |
65 | f0cbd3ec | bellard | #ifndef HAVE_STRERROR
|
66 | f0cbd3ec | bellard | |
67 | f0cbd3ec | bellard | /*
|
68 | f0cbd3ec | bellard | * For systems with no strerror
|
69 | f0cbd3ec | bellard | */
|
70 | f0cbd3ec | bellard | |
71 | f0cbd3ec | bellard | extern int sys_nerr; |
72 | f0cbd3ec | bellard | extern char *sys_errlist[]; |
73 | f0cbd3ec | bellard | |
74 | f0cbd3ec | bellard | char *
|
75 | f0cbd3ec | bellard | strerror(error) |
76 | f0cbd3ec | bellard | int error;
|
77 | f0cbd3ec | bellard | { |
78 | f0cbd3ec | bellard | if (error < sys_nerr)
|
79 | f0cbd3ec | bellard | return sys_errlist[error];
|
80 | f0cbd3ec | bellard | else
|
81 | f0cbd3ec | bellard | return "Unknown error."; |
82 | f0cbd3ec | bellard | } |
83 | f0cbd3ec | bellard | |
84 | f0cbd3ec | bellard | #endif
|
85 | f0cbd3ec | bellard | |
86 | f0cbd3ec | bellard | |
87 | a3d4af03 | bellard | #ifdef _WIN32
|
88 | a3d4af03 | bellard | |
89 | a3d4af03 | bellard | int
|
90 | 9634d903 | blueswir1 | fork_exec(struct socket *so, const char *ex, int do_pty) |
91 | a3d4af03 | bellard | { |
92 | a3d4af03 | bellard | /* not implemented */
|
93 | a3d4af03 | bellard | return 0; |
94 | a3d4af03 | bellard | } |
95 | a3d4af03 | bellard | |
96 | a3d4af03 | bellard | #else
|
97 | a3d4af03 | bellard | |
98 | f0cbd3ec | bellard | /*
|
99 | f0cbd3ec | bellard | * XXX This is ugly
|
100 | f0cbd3ec | bellard | * We create and bind a socket, then fork off to another
|
101 | f0cbd3ec | bellard | * process, which connects to this socket, after which we
|
102 | f0cbd3ec | bellard | * exec the wanted program. If something (strange) happens,
|
103 | f0cbd3ec | bellard | * the accept() call could block us forever.
|
104 | 5fafdf24 | ths | *
|
105 | f0cbd3ec | bellard | * do_pty = 0 Fork/exec inetd style
|
106 | f0cbd3ec | bellard | * do_pty = 1 Fork/exec using slirp.telnetd
|
107 | f0cbd3ec | bellard | * do_ptr = 2 Fork/exec using pty
|
108 | f0cbd3ec | bellard | */
|
109 | f0cbd3ec | bellard | int
|
110 | 9634d903 | blueswir1 | fork_exec(struct socket *so, const char *ex, int do_pty) |
111 | f0cbd3ec | bellard | { |
112 | f0cbd3ec | bellard | int s;
|
113 | f0cbd3ec | bellard | struct sockaddr_in addr;
|
114 | 242acf3a | balrog | socklen_t addrlen = sizeof(addr);
|
115 | f0cbd3ec | bellard | int opt;
|
116 | 9634d903 | blueswir1 | int master = -1; |
117 | 7ccfb2eb | blueswir1 | const char *argv[256]; |
118 | f0cbd3ec | bellard | /* don't want to clobber the original */
|
119 | f0cbd3ec | bellard | char *bptr;
|
120 | 9634d903 | blueswir1 | const char *curarg; |
121 | 7b91a172 | bellard | int c, i, ret;
|
122 | 4d54ec78 | Paolo Bonzini | pid_t pid; |
123 | 5fafdf24 | ths | |
124 | f0cbd3ec | bellard | DEBUG_CALL("fork_exec");
|
125 | f0cbd3ec | bellard | DEBUG_ARG("so = %lx", (long)so); |
126 | f0cbd3ec | bellard | DEBUG_ARG("ex = %lx", (long)ex); |
127 | f0cbd3ec | bellard | DEBUG_ARG("do_pty = %lx", (long)do_pty); |
128 | 5fafdf24 | ths | |
129 | f0cbd3ec | bellard | if (do_pty == 2) { |
130 | 3f9b2b1f | balrog | return 0; |
131 | f0cbd3ec | bellard | } else {
|
132 | f0cbd3ec | bellard | addr.sin_family = AF_INET; |
133 | f0cbd3ec | bellard | addr.sin_port = 0;
|
134 | f0cbd3ec | bellard | addr.sin_addr.s_addr = INADDR_ANY; |
135 | 3b46e624 | ths | |
136 | 40ff6d7e | Kevin Wolf | if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 || |
137 | f0cbd3ec | bellard | bind(s, (struct sockaddr *)&addr, addrlen) < 0 || |
138 | f0cbd3ec | bellard | listen(s, 1) < 0) { |
139 | f0cbd3ec | bellard | lprint("Error: inet socket: %s\n", strerror(errno));
|
140 | 379ff53d | bellard | closesocket(s); |
141 | 3b46e624 | ths | |
142 | f0cbd3ec | bellard | return 0; |
143 | f0cbd3ec | bellard | } |
144 | f0cbd3ec | bellard | } |
145 | 5fafdf24 | ths | |
146 | 4d54ec78 | Paolo Bonzini | pid = fork(); |
147 | 4d54ec78 | Paolo Bonzini | switch(pid) {
|
148 | f0cbd3ec | bellard | case -1: |
149 | f0cbd3ec | bellard | lprint("Error: fork failed: %s\n", strerror(errno));
|
150 | f0cbd3ec | bellard | close(s); |
151 | f0cbd3ec | bellard | if (do_pty == 2) |
152 | f0cbd3ec | bellard | close(master); |
153 | f0cbd3ec | bellard | return 0; |
154 | 3b46e624 | ths | |
155 | f0cbd3ec | bellard | case 0: |
156 | f0cbd3ec | bellard | /* Set the DISPLAY */
|
157 | f0cbd3ec | bellard | if (do_pty == 2) { |
158 | f0cbd3ec | bellard | (void) close(master);
|
159 | f0cbd3ec | bellard | #ifdef TIOCSCTTY /* XXXXX */ |
160 | f0cbd3ec | bellard | (void) setsid();
|
161 | f0cbd3ec | bellard | ioctl(s, TIOCSCTTY, (char *)NULL); |
162 | f0cbd3ec | bellard | #endif
|
163 | f0cbd3ec | bellard | } else {
|
164 | f0cbd3ec | bellard | getsockname(s, (struct sockaddr *)&addr, &addrlen);
|
165 | f0cbd3ec | bellard | close(s); |
166 | f0cbd3ec | bellard | /*
|
167 | f0cbd3ec | bellard | * Connect to the socket
|
168 | f0cbd3ec | bellard | * XXX If any of these fail, we're in trouble!
|
169 | f0cbd3ec | bellard | */
|
170 | 40ff6d7e | Kevin Wolf | s = qemu_socket(AF_INET, SOCK_STREAM, 0);
|
171 | f0cbd3ec | bellard | addr.sin_addr = loopback_addr; |
172 | 7b91a172 | bellard | do {
|
173 | 7b91a172 | bellard | ret = connect(s, (struct sockaddr *)&addr, addrlen);
|
174 | 7b91a172 | bellard | } while (ret < 0 && errno == EINTR); |
175 | f0cbd3ec | bellard | } |
176 | 3b46e624 | ths | |
177 | f0cbd3ec | bellard | dup2(s, 0);
|
178 | f0cbd3ec | bellard | dup2(s, 1);
|
179 | f0cbd3ec | bellard | dup2(s, 2);
|
180 | 9634d903 | blueswir1 | for (s = getdtablesize() - 1; s >= 3; s--) |
181 | f0cbd3ec | bellard | close(s); |
182 | 3b46e624 | ths | |
183 | f0cbd3ec | bellard | i = 0;
|
184 | 6265eb26 | Jim Meyering | bptr = qemu_strdup(ex); /* No need to free() this */
|
185 | f0cbd3ec | bellard | if (do_pty == 1) { |
186 | f0cbd3ec | bellard | /* Setup "slirp.telnetd -x" */
|
187 | f0cbd3ec | bellard | argv[i++] = "slirp.telnetd";
|
188 | f0cbd3ec | bellard | argv[i++] = "-x";
|
189 | f0cbd3ec | bellard | argv[i++] = bptr; |
190 | f0cbd3ec | bellard | } else
|
191 | f0cbd3ec | bellard | do {
|
192 | f0cbd3ec | bellard | /* Change the string into argv[] */
|
193 | f0cbd3ec | bellard | curarg = bptr; |
194 | f0cbd3ec | bellard | while (*bptr != ' ' && *bptr != (char)0) |
195 | f0cbd3ec | bellard | bptr++; |
196 | f0cbd3ec | bellard | c = *bptr; |
197 | f0cbd3ec | bellard | *bptr++ = (char)0; |
198 | f0cbd3ec | bellard | argv[i++] = strdup(curarg); |
199 | f0cbd3ec | bellard | } while (c);
|
200 | 3b46e624 | ths | |
201 | 511d2b14 | blueswir1 | argv[i] = NULL;
|
202 | 7ccfb2eb | blueswir1 | execvp(argv[0], (char **)argv); |
203 | 3b46e624 | ths | |
204 | f0cbd3ec | bellard | /* Ooops, failed, let's tell the user why */
|
205 | f0d98b05 | Kirill A. Shutemov | fprintf(stderr, "Error: execvp of %s failed: %s\n",
|
206 | f0d98b05 | Kirill A. Shutemov | argv[0], strerror(errno));
|
207 | f0cbd3ec | bellard | close(0); close(1); close(2); /* XXX */ |
208 | f0cbd3ec | bellard | exit(1);
|
209 | 3b46e624 | ths | |
210 | f0cbd3ec | bellard | default:
|
211 | 4d54ec78 | Paolo Bonzini | qemu_add_child_watch(pid); |
212 | f0cbd3ec | bellard | if (do_pty == 2) { |
213 | f0cbd3ec | bellard | close(s); |
214 | f0cbd3ec | bellard | so->s = master; |
215 | f0cbd3ec | bellard | } else {
|
216 | f0cbd3ec | bellard | /*
|
217 | f0cbd3ec | bellard | * XXX this could block us...
|
218 | f0cbd3ec | bellard | * XXX Should set a timer here, and if accept() doesn't
|
219 | f0cbd3ec | bellard | * return after X seconds, declare it a failure
|
220 | f0cbd3ec | bellard | * The only reason this will block forever is if socket()
|
221 | f0cbd3ec | bellard | * of connect() fail in the child process
|
222 | f0cbd3ec | bellard | */
|
223 | 7b91a172 | bellard | do {
|
224 | 7b91a172 | bellard | so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
|
225 | 7b91a172 | bellard | } while (so->s < 0 && errno == EINTR); |
226 | 7b91a172 | bellard | closesocket(s); |
227 | f0cbd3ec | bellard | opt = 1;
|
228 | f0cbd3ec | bellard | setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); |
229 | f0cbd3ec | bellard | opt = 1;
|
230 | f0cbd3ec | bellard | setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); |
231 | f0cbd3ec | bellard | } |
232 | f0cbd3ec | bellard | fd_nonblock(so->s); |
233 | 3b46e624 | ths | |
234 | f0cbd3ec | bellard | /* Append the telnet options now */
|
235 | 511d2b14 | blueswir1 | if (so->so_m != NULL && do_pty == 1) { |
236 | f0cbd3ec | bellard | sbappend(so, so->so_m); |
237 | 511d2b14 | blueswir1 | so->so_m = NULL;
|
238 | f0cbd3ec | bellard | } |
239 | 3b46e624 | ths | |
240 | f0cbd3ec | bellard | return 1; |
241 | f0cbd3ec | bellard | } |
242 | f0cbd3ec | bellard | } |
243 | f0cbd3ec | bellard | #endif
|
244 | f0cbd3ec | bellard | |
245 | f0cbd3ec | bellard | #ifndef HAVE_STRDUP
|
246 | f0cbd3ec | bellard | char *
|
247 | f0cbd3ec | bellard | strdup(str) |
248 | f0cbd3ec | bellard | const char *str; |
249 | f0cbd3ec | bellard | { |
250 | f0cbd3ec | bellard | char *bptr;
|
251 | 5fafdf24 | ths | |
252 | f0cbd3ec | bellard | bptr = (char *)malloc(strlen(str)+1); |
253 | f0cbd3ec | bellard | strcpy(bptr, str); |
254 | 5fafdf24 | ths | |
255 | f0cbd3ec | bellard | return bptr;
|
256 | f0cbd3ec | bellard | } |
257 | f0cbd3ec | bellard | #endif
|
258 | f0cbd3ec | bellard | |
259 | 376253ec | aliguori | #include "monitor.h" |
260 | c9f10306 | ths | |
261 | 31a60e22 | blueswir1 | void lprint(const char *format, ...) |
262 | 31a60e22 | blueswir1 | { |
263 | 31a60e22 | blueswir1 | va_list args; |
264 | 31a60e22 | blueswir1 | |
265 | 31a60e22 | blueswir1 | va_start(args, format); |
266 | 8631b608 | Markus Armbruster | monitor_vprintf(default_mon, format, args); |
267 | 31a60e22 | blueswir1 | va_end(args); |
268 | 31a60e22 | blueswir1 | } |
269 | f0cbd3ec | bellard | |
270 | f0cbd3ec | bellard | void
|
271 | 511d2b14 | blueswir1 | u_sleep(int usec)
|
272 | f0cbd3ec | bellard | { |
273 | f0cbd3ec | bellard | struct timeval t;
|
274 | f0cbd3ec | bellard | fd_set fdset; |
275 | 5fafdf24 | ths | |
276 | f0cbd3ec | bellard | FD_ZERO(&fdset); |
277 | 5fafdf24 | ths | |
278 | f0cbd3ec | bellard | t.tv_sec = 0;
|
279 | f0cbd3ec | bellard | t.tv_usec = usec * 1000;
|
280 | 5fafdf24 | ths | |
281 | f0cbd3ec | bellard | select(0, &fdset, &fdset, &fdset, &t);
|
282 | f0cbd3ec | bellard | } |
283 | f0cbd3ec | bellard | |
284 | f0cbd3ec | bellard | /*
|
285 | f0cbd3ec | bellard | * Set fd blocking and non-blocking
|
286 | f0cbd3ec | bellard | */
|
287 | f0cbd3ec | bellard | |
288 | f0cbd3ec | bellard | void
|
289 | 511d2b14 | blueswir1 | fd_nonblock(int fd)
|
290 | f0cbd3ec | bellard | { |
291 | f0cbd3ec | bellard | #ifdef FIONBIO
|
292 | b9e82a59 | blueswir1 | #ifdef _WIN32
|
293 | c5b76b38 | Blue Swirl | unsigned long opt = 1; |
294 | b9e82a59 | blueswir1 | #else
|
295 | b9e82a59 | blueswir1 | int opt = 1; |
296 | b9e82a59 | blueswir1 | #endif
|
297 | 5fafdf24 | ths | |
298 | 379ff53d | bellard | ioctlsocket(fd, FIONBIO, &opt); |
299 | f0cbd3ec | bellard | #else
|
300 | f0cbd3ec | bellard | int opt;
|
301 | 5fafdf24 | ths | |
302 | f0cbd3ec | bellard | opt = fcntl(fd, F_GETFL, 0);
|
303 | f0cbd3ec | bellard | opt |= O_NONBLOCK; |
304 | f0cbd3ec | bellard | fcntl(fd, F_SETFL, opt); |
305 | f0cbd3ec | bellard | #endif
|
306 | f0cbd3ec | bellard | } |
307 | f0cbd3ec | bellard | |
308 | f0cbd3ec | bellard | void
|
309 | 511d2b14 | blueswir1 | fd_block(int fd)
|
310 | f0cbd3ec | bellard | { |
311 | f0cbd3ec | bellard | #ifdef FIONBIO
|
312 | c5b76b38 | Blue Swirl | #ifdef _WIN32
|
313 | c5b76b38 | Blue Swirl | unsigned long opt = 0; |
314 | c5b76b38 | Blue Swirl | #else
|
315 | f0cbd3ec | bellard | int opt = 0; |
316 | c5b76b38 | Blue Swirl | #endif
|
317 | 5fafdf24 | ths | |
318 | 379ff53d | bellard | ioctlsocket(fd, FIONBIO, &opt); |
319 | f0cbd3ec | bellard | #else
|
320 | f0cbd3ec | bellard | int opt;
|
321 | 5fafdf24 | ths | |
322 | f0cbd3ec | bellard | opt = fcntl(fd, F_GETFL, 0);
|
323 | f0cbd3ec | bellard | opt &= ~O_NONBLOCK; |
324 | f0cbd3ec | bellard | fcntl(fd, F_SETFL, opt); |
325 | f0cbd3ec | bellard | #endif
|
326 | f0cbd3ec | bellard | } |
327 | f0cbd3ec | bellard | |
328 | 9f8bd042 | Jan Kiszka | void slirp_connection_info(Slirp *slirp, Monitor *mon)
|
329 | 6dbe553f | Jan Kiszka | { |
330 | 6dbe553f | Jan Kiszka | const char * const tcpstates[] = { |
331 | 6dbe553f | Jan Kiszka | [TCPS_CLOSED] = "CLOSED",
|
332 | 6dbe553f | Jan Kiszka | [TCPS_LISTEN] = "LISTEN",
|
333 | 6dbe553f | Jan Kiszka | [TCPS_SYN_SENT] = "SYN_SENT",
|
334 | 6dbe553f | Jan Kiszka | [TCPS_SYN_RECEIVED] = "SYN_RCVD",
|
335 | 6dbe553f | Jan Kiszka | [TCPS_ESTABLISHED] = "ESTABLISHED",
|
336 | 6dbe553f | Jan Kiszka | [TCPS_CLOSE_WAIT] = "CLOSE_WAIT",
|
337 | 6dbe553f | Jan Kiszka | [TCPS_FIN_WAIT_1] = "FIN_WAIT_1",
|
338 | 6dbe553f | Jan Kiszka | [TCPS_CLOSING] = "CLOSING",
|
339 | 6dbe553f | Jan Kiszka | [TCPS_LAST_ACK] = "LAST_ACK",
|
340 | 6dbe553f | Jan Kiszka | [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
|
341 | 6dbe553f | Jan Kiszka | [TCPS_TIME_WAIT] = "TIME_WAIT",
|
342 | 6dbe553f | Jan Kiszka | }; |
343 | 6dbe553f | Jan Kiszka | struct in_addr dst_addr;
|
344 | 6dbe553f | Jan Kiszka | struct sockaddr_in src;
|
345 | 6dbe553f | Jan Kiszka | socklen_t src_len; |
346 | 6dbe553f | Jan Kiszka | uint16_t dst_port; |
347 | 6dbe553f | Jan Kiszka | struct socket *so;
|
348 | 6dbe553f | Jan Kiszka | const char *state; |
349 | 6dbe553f | Jan Kiszka | char buf[20]; |
350 | 6dbe553f | Jan Kiszka | int n;
|
351 | 6dbe553f | Jan Kiszka | |
352 | 6dbe553f | Jan Kiszka | monitor_printf(mon, " Protocol[State] FD Source Address Port "
|
353 | 6dbe553f | Jan Kiszka | "Dest. Address Port RecvQ SendQ\n");
|
354 | 6dbe553f | Jan Kiszka | |
355 | 460fec67 | Jan Kiszka | for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
|
356 | 6dbe553f | Jan Kiszka | if (so->so_state & SS_HOSTFWD) {
|
357 | 6dbe553f | Jan Kiszka | state = "HOST_FORWARD";
|
358 | 6dbe553f | Jan Kiszka | } else if (so->so_tcpcb) { |
359 | 6dbe553f | Jan Kiszka | state = tcpstates[so->so_tcpcb->t_state]; |
360 | 6dbe553f | Jan Kiszka | } else {
|
361 | 6dbe553f | Jan Kiszka | state = "NONE";
|
362 | 6dbe553f | Jan Kiszka | } |
363 | 6dbe553f | Jan Kiszka | if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
|
364 | 6dbe553f | Jan Kiszka | src_len = sizeof(src);
|
365 | 6dbe553f | Jan Kiszka | getsockname(so->s, (struct sockaddr *)&src, &src_len);
|
366 | 6dbe553f | Jan Kiszka | dst_addr = so->so_laddr; |
367 | 6dbe553f | Jan Kiszka | dst_port = so->so_lport; |
368 | 6dbe553f | Jan Kiszka | } else {
|
369 | 6dbe553f | Jan Kiszka | src.sin_addr = so->so_laddr; |
370 | 6dbe553f | Jan Kiszka | src.sin_port = so->so_lport; |
371 | 6dbe553f | Jan Kiszka | dst_addr = so->so_faddr; |
372 | 6dbe553f | Jan Kiszka | dst_port = so->so_fport; |
373 | 6dbe553f | Jan Kiszka | } |
374 | 6dbe553f | Jan Kiszka | n = snprintf(buf, sizeof(buf), " TCP[%s]", state); |
375 | 6dbe553f | Jan Kiszka | memset(&buf[n], ' ', 19 - n); |
376 | 6dbe553f | Jan Kiszka | buf[19] = 0; |
377 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
|
378 | 6dbe553f | Jan Kiszka | src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
|
379 | 6dbe553f | Jan Kiszka | ntohs(src.sin_port)); |
380 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%15s %5d %5d %5d\n",
|
381 | 6dbe553f | Jan Kiszka | inet_ntoa(dst_addr), ntohs(dst_port), |
382 | 6dbe553f | Jan Kiszka | so->so_rcv.sb_cc, so->so_snd.sb_cc); |
383 | 6dbe553f | Jan Kiszka | } |
384 | 6dbe553f | Jan Kiszka | |
385 | 460fec67 | Jan Kiszka | for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
|
386 | 6dbe553f | Jan Kiszka | if (so->so_state & SS_HOSTFWD) {
|
387 | 6dbe553f | Jan Kiszka | n = snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]"); |
388 | 6dbe553f | Jan Kiszka | src_len = sizeof(src);
|
389 | 6dbe553f | Jan Kiszka | getsockname(so->s, (struct sockaddr *)&src, &src_len);
|
390 | 6dbe553f | Jan Kiszka | dst_addr = so->so_laddr; |
391 | 6dbe553f | Jan Kiszka | dst_port = so->so_lport; |
392 | 6dbe553f | Jan Kiszka | } else {
|
393 | 6dbe553f | Jan Kiszka | n = snprintf(buf, sizeof(buf), " UDP[%d sec]", |
394 | 6dbe553f | Jan Kiszka | (so->so_expire - curtime) / 1000);
|
395 | 6dbe553f | Jan Kiszka | src.sin_addr = so->so_laddr; |
396 | 6dbe553f | Jan Kiszka | src.sin_port = so->so_lport; |
397 | 6dbe553f | Jan Kiszka | dst_addr = so->so_faddr; |
398 | 6dbe553f | Jan Kiszka | dst_port = so->so_fport; |
399 | 6dbe553f | Jan Kiszka | } |
400 | 6dbe553f | Jan Kiszka | memset(&buf[n], ' ', 19 - n); |
401 | 6dbe553f | Jan Kiszka | buf[19] = 0; |
402 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
|
403 | 6dbe553f | Jan Kiszka | src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
|
404 | 6dbe553f | Jan Kiszka | ntohs(src.sin_port)); |
405 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%15s %5d %5d %5d\n",
|
406 | 6dbe553f | Jan Kiszka | inet_ntoa(dst_addr), ntohs(dst_port), |
407 | 6dbe553f | Jan Kiszka | so->so_rcv.sb_cc, so->so_snd.sb_cc); |
408 | 6dbe553f | Jan Kiszka | } |
409 | 6dbe553f | Jan Kiszka | } |