root / slirp / misc.c @ d82287de
History | View | Annotate | Download (9.3 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 | 83c9089e | Paolo Bonzini | #include "monitor/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 | 7ccfb2eb | blueswir1 | const char *argv[256]; |
117 | f0cbd3ec | bellard | /* don't want to clobber the original */
|
118 | f0cbd3ec | bellard | char *bptr;
|
119 | 9634d903 | blueswir1 | const char *curarg; |
120 | 7b91a172 | bellard | int c, i, ret;
|
121 | 4d54ec78 | Paolo Bonzini | pid_t pid; |
122 | 5fafdf24 | ths | |
123 | f0cbd3ec | bellard | DEBUG_CALL("fork_exec");
|
124 | f0cbd3ec | bellard | DEBUG_ARG("so = %lx", (long)so); |
125 | f0cbd3ec | bellard | DEBUG_ARG("ex = %lx", (long)ex); |
126 | f0cbd3ec | bellard | DEBUG_ARG("do_pty = %lx", (long)do_pty); |
127 | 5fafdf24 | ths | |
128 | f0cbd3ec | bellard | if (do_pty == 2) { |
129 | 3f9b2b1f | balrog | return 0; |
130 | f0cbd3ec | bellard | } else {
|
131 | f0cbd3ec | bellard | addr.sin_family = AF_INET; |
132 | f0cbd3ec | bellard | addr.sin_port = 0;
|
133 | f0cbd3ec | bellard | addr.sin_addr.s_addr = INADDR_ANY; |
134 | 3b46e624 | ths | |
135 | 40ff6d7e | Kevin Wolf | if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 || |
136 | f0cbd3ec | bellard | bind(s, (struct sockaddr *)&addr, addrlen) < 0 || |
137 | f0cbd3ec | bellard | listen(s, 1) < 0) { |
138 | f0cbd3ec | bellard | lprint("Error: inet socket: %s\n", strerror(errno));
|
139 | 379ff53d | bellard | closesocket(s); |
140 | 3b46e624 | ths | |
141 | f0cbd3ec | bellard | return 0; |
142 | f0cbd3ec | bellard | } |
143 | f0cbd3ec | bellard | } |
144 | 5fafdf24 | ths | |
145 | 4d54ec78 | Paolo Bonzini | pid = fork(); |
146 | 4d54ec78 | Paolo Bonzini | switch(pid) {
|
147 | f0cbd3ec | bellard | case -1: |
148 | f0cbd3ec | bellard | lprint("Error: fork failed: %s\n", strerror(errno));
|
149 | f0cbd3ec | bellard | close(s); |
150 | f0cbd3ec | bellard | return 0; |
151 | 3b46e624 | ths | |
152 | f0cbd3ec | bellard | case 0: |
153 | 565465fc | Jan Kiszka | setsid(); |
154 | 565465fc | Jan Kiszka | |
155 | f0cbd3ec | bellard | /* Set the DISPLAY */
|
156 | 9f1134d4 | Stefan Weil | getsockname(s, (struct sockaddr *)&addr, &addrlen);
|
157 | 9f1134d4 | Stefan Weil | close(s); |
158 | 9f1134d4 | Stefan Weil | /*
|
159 | 9f1134d4 | Stefan Weil | * Connect to the socket
|
160 | 9f1134d4 | Stefan Weil | * XXX If any of these fail, we're in trouble!
|
161 | 9f1134d4 | Stefan Weil | */
|
162 | 9f1134d4 | Stefan Weil | s = qemu_socket(AF_INET, SOCK_STREAM, 0);
|
163 | 9f1134d4 | Stefan Weil | addr.sin_addr = loopback_addr; |
164 | 9f1134d4 | Stefan Weil | do {
|
165 | 9f1134d4 | Stefan Weil | ret = connect(s, (struct sockaddr *)&addr, addrlen);
|
166 | 9f1134d4 | Stefan Weil | } while (ret < 0 && errno == EINTR); |
167 | 3b46e624 | ths | |
168 | f0cbd3ec | bellard | dup2(s, 0);
|
169 | f0cbd3ec | bellard | dup2(s, 1);
|
170 | f0cbd3ec | bellard | dup2(s, 2);
|
171 | 9634d903 | blueswir1 | for (s = getdtablesize() - 1; s >= 3; s--) |
172 | f0cbd3ec | bellard | close(s); |
173 | 3b46e624 | ths | |
174 | f0cbd3ec | bellard | i = 0;
|
175 | 7267c094 | Anthony Liguori | bptr = g_strdup(ex); /* No need to free() this */
|
176 | f0cbd3ec | bellard | if (do_pty == 1) { |
177 | f0cbd3ec | bellard | /* Setup "slirp.telnetd -x" */
|
178 | f0cbd3ec | bellard | argv[i++] = "slirp.telnetd";
|
179 | f0cbd3ec | bellard | argv[i++] = "-x";
|
180 | f0cbd3ec | bellard | argv[i++] = bptr; |
181 | f0cbd3ec | bellard | } else
|
182 | f0cbd3ec | bellard | do {
|
183 | f0cbd3ec | bellard | /* Change the string into argv[] */
|
184 | f0cbd3ec | bellard | curarg = bptr; |
185 | f0cbd3ec | bellard | while (*bptr != ' ' && *bptr != (char)0) |
186 | f0cbd3ec | bellard | bptr++; |
187 | f0cbd3ec | bellard | c = *bptr; |
188 | f0cbd3ec | bellard | *bptr++ = (char)0; |
189 | f0cbd3ec | bellard | argv[i++] = strdup(curarg); |
190 | f0cbd3ec | bellard | } while (c);
|
191 | 3b46e624 | ths | |
192 | 511d2b14 | blueswir1 | argv[i] = NULL;
|
193 | 7ccfb2eb | blueswir1 | execvp(argv[0], (char **)argv); |
194 | 3b46e624 | ths | |
195 | f0cbd3ec | bellard | /* Ooops, failed, let's tell the user why */
|
196 | f0d98b05 | Kirill A. Shutemov | fprintf(stderr, "Error: execvp of %s failed: %s\n",
|
197 | f0d98b05 | Kirill A. Shutemov | argv[0], strerror(errno));
|
198 | f0cbd3ec | bellard | close(0); close(1); close(2); /* XXX */ |
199 | f0cbd3ec | bellard | exit(1);
|
200 | 3b46e624 | ths | |
201 | f0cbd3ec | bellard | default:
|
202 | 4d54ec78 | Paolo Bonzini | qemu_add_child_watch(pid); |
203 | 9f1134d4 | Stefan Weil | /*
|
204 | 9f1134d4 | Stefan Weil | * XXX this could block us...
|
205 | 9f1134d4 | Stefan Weil | * XXX Should set a timer here, and if accept() doesn't
|
206 | 9f1134d4 | Stefan Weil | * return after X seconds, declare it a failure
|
207 | 9f1134d4 | Stefan Weil | * The only reason this will block forever is if socket()
|
208 | 9f1134d4 | Stefan Weil | * of connect() fail in the child process
|
209 | 9f1134d4 | Stefan Weil | */
|
210 | 9f1134d4 | Stefan Weil | do {
|
211 | 9f1134d4 | Stefan Weil | so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
|
212 | 9f1134d4 | Stefan Weil | } while (so->s < 0 && errno == EINTR); |
213 | 9f1134d4 | Stefan Weil | closesocket(s); |
214 | 9f1134d4 | Stefan Weil | opt = 1;
|
215 | 9f1134d4 | Stefan Weil | setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)); |
216 | 9f1134d4 | Stefan Weil | opt = 1;
|
217 | 9f1134d4 | Stefan Weil | setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int)); |
218 | 1c5970a8 | Paolo Bonzini | socket_set_nonblock(so->s); |
219 | 3b46e624 | ths | |
220 | f0cbd3ec | bellard | /* Append the telnet options now */
|
221 | 511d2b14 | blueswir1 | if (so->so_m != NULL && do_pty == 1) { |
222 | f0cbd3ec | bellard | sbappend(so, so->so_m); |
223 | 511d2b14 | blueswir1 | so->so_m = NULL;
|
224 | f0cbd3ec | bellard | } |
225 | 3b46e624 | ths | |
226 | f0cbd3ec | bellard | return 1; |
227 | f0cbd3ec | bellard | } |
228 | f0cbd3ec | bellard | } |
229 | f0cbd3ec | bellard | #endif
|
230 | f0cbd3ec | bellard | |
231 | f0cbd3ec | bellard | #ifndef HAVE_STRDUP
|
232 | f0cbd3ec | bellard | char *
|
233 | f0cbd3ec | bellard | strdup(str) |
234 | f0cbd3ec | bellard | const char *str; |
235 | f0cbd3ec | bellard | { |
236 | f0cbd3ec | bellard | char *bptr;
|
237 | 5fafdf24 | ths | |
238 | f0cbd3ec | bellard | bptr = (char *)malloc(strlen(str)+1); |
239 | f0cbd3ec | bellard | strcpy(bptr, str); |
240 | 5fafdf24 | ths | |
241 | f0cbd3ec | bellard | return bptr;
|
242 | f0cbd3ec | bellard | } |
243 | f0cbd3ec | bellard | #endif
|
244 | f0cbd3ec | bellard | |
245 | 83c9089e | Paolo Bonzini | #include "monitor/monitor.h" |
246 | c9f10306 | ths | |
247 | 31a60e22 | blueswir1 | void lprint(const char *format, ...) |
248 | 31a60e22 | blueswir1 | { |
249 | 31a60e22 | blueswir1 | va_list args; |
250 | 31a60e22 | blueswir1 | |
251 | 31a60e22 | blueswir1 | va_start(args, format); |
252 | 8631b608 | Markus Armbruster | monitor_vprintf(default_mon, format, args); |
253 | 31a60e22 | blueswir1 | va_end(args); |
254 | 31a60e22 | blueswir1 | } |
255 | f0cbd3ec | bellard | |
256 | 9f8bd042 | Jan Kiszka | void slirp_connection_info(Slirp *slirp, Monitor *mon)
|
257 | 6dbe553f | Jan Kiszka | { |
258 | 6dbe553f | Jan Kiszka | const char * const tcpstates[] = { |
259 | 6dbe553f | Jan Kiszka | [TCPS_CLOSED] = "CLOSED",
|
260 | 6dbe553f | Jan Kiszka | [TCPS_LISTEN] = "LISTEN",
|
261 | 6dbe553f | Jan Kiszka | [TCPS_SYN_SENT] = "SYN_SENT",
|
262 | 6dbe553f | Jan Kiszka | [TCPS_SYN_RECEIVED] = "SYN_RCVD",
|
263 | 6dbe553f | Jan Kiszka | [TCPS_ESTABLISHED] = "ESTABLISHED",
|
264 | 6dbe553f | Jan Kiszka | [TCPS_CLOSE_WAIT] = "CLOSE_WAIT",
|
265 | 6dbe553f | Jan Kiszka | [TCPS_FIN_WAIT_1] = "FIN_WAIT_1",
|
266 | 6dbe553f | Jan Kiszka | [TCPS_CLOSING] = "CLOSING",
|
267 | 6dbe553f | Jan Kiszka | [TCPS_LAST_ACK] = "LAST_ACK",
|
268 | 6dbe553f | Jan Kiszka | [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
|
269 | 6dbe553f | Jan Kiszka | [TCPS_TIME_WAIT] = "TIME_WAIT",
|
270 | 6dbe553f | Jan Kiszka | }; |
271 | 6dbe553f | Jan Kiszka | struct in_addr dst_addr;
|
272 | 6dbe553f | Jan Kiszka | struct sockaddr_in src;
|
273 | 6dbe553f | Jan Kiszka | socklen_t src_len; |
274 | 6dbe553f | Jan Kiszka | uint16_t dst_port; |
275 | 6dbe553f | Jan Kiszka | struct socket *so;
|
276 | 6dbe553f | Jan Kiszka | const char *state; |
277 | 6dbe553f | Jan Kiszka | char buf[20]; |
278 | 6dbe553f | Jan Kiszka | |
279 | 6dbe553f | Jan Kiszka | monitor_printf(mon, " Protocol[State] FD Source Address Port "
|
280 | 6dbe553f | Jan Kiszka | "Dest. Address Port RecvQ SendQ\n");
|
281 | 6dbe553f | Jan Kiszka | |
282 | 460fec67 | Jan Kiszka | for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
|
283 | 6dbe553f | Jan Kiszka | if (so->so_state & SS_HOSTFWD) {
|
284 | 6dbe553f | Jan Kiszka | state = "HOST_FORWARD";
|
285 | 6dbe553f | Jan Kiszka | } else if (so->so_tcpcb) { |
286 | 6dbe553f | Jan Kiszka | state = tcpstates[so->so_tcpcb->t_state]; |
287 | 6dbe553f | Jan Kiszka | } else {
|
288 | 6dbe553f | Jan Kiszka | state = "NONE";
|
289 | 6dbe553f | Jan Kiszka | } |
290 | 6dbe553f | Jan Kiszka | if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
|
291 | 6dbe553f | Jan Kiszka | src_len = sizeof(src);
|
292 | 6dbe553f | Jan Kiszka | getsockname(so->s, (struct sockaddr *)&src, &src_len);
|
293 | 6dbe553f | Jan Kiszka | dst_addr = so->so_laddr; |
294 | 6dbe553f | Jan Kiszka | dst_port = so->so_lport; |
295 | 6dbe553f | Jan Kiszka | } else {
|
296 | 6dbe553f | Jan Kiszka | src.sin_addr = so->so_laddr; |
297 | 6dbe553f | Jan Kiszka | src.sin_port = so->so_lport; |
298 | 6dbe553f | Jan Kiszka | dst_addr = so->so_faddr; |
299 | 6dbe553f | Jan Kiszka | dst_port = so->so_fport; |
300 | 6dbe553f | Jan Kiszka | } |
301 | f293d8b1 | Alon Levy | snprintf(buf, sizeof(buf), " TCP[%s]", state); |
302 | f293d8b1 | Alon Levy | monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
|
303 | 6dbe553f | Jan Kiszka | src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
|
304 | 6dbe553f | Jan Kiszka | ntohs(src.sin_port)); |
305 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%15s %5d %5d %5d\n",
|
306 | 6dbe553f | Jan Kiszka | inet_ntoa(dst_addr), ntohs(dst_port), |
307 | 6dbe553f | Jan Kiszka | so->so_rcv.sb_cc, so->so_snd.sb_cc); |
308 | 6dbe553f | Jan Kiszka | } |
309 | 6dbe553f | Jan Kiszka | |
310 | 460fec67 | Jan Kiszka | for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
|
311 | 6dbe553f | Jan Kiszka | if (so->so_state & SS_HOSTFWD) {
|
312 | f293d8b1 | Alon Levy | snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]"); |
313 | 6dbe553f | Jan Kiszka | src_len = sizeof(src);
|
314 | 6dbe553f | Jan Kiszka | getsockname(so->s, (struct sockaddr *)&src, &src_len);
|
315 | 6dbe553f | Jan Kiszka | dst_addr = so->so_laddr; |
316 | 6dbe553f | Jan Kiszka | dst_port = so->so_lport; |
317 | 6dbe553f | Jan Kiszka | } else {
|
318 | f293d8b1 | Alon Levy | snprintf(buf, sizeof(buf), " UDP[%d sec]", |
319 | 6dbe553f | Jan Kiszka | (so->so_expire - curtime) / 1000);
|
320 | 6dbe553f | Jan Kiszka | src.sin_addr = so->so_laddr; |
321 | 6dbe553f | Jan Kiszka | src.sin_port = so->so_lport; |
322 | 6dbe553f | Jan Kiszka | dst_addr = so->so_faddr; |
323 | 6dbe553f | Jan Kiszka | dst_port = so->so_fport; |
324 | 6dbe553f | Jan Kiszka | } |
325 | f293d8b1 | Alon Levy | monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
|
326 | 6dbe553f | Jan Kiszka | src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
|
327 | 6dbe553f | Jan Kiszka | ntohs(src.sin_port)); |
328 | 6dbe553f | Jan Kiszka | monitor_printf(mon, "%15s %5d %5d %5d\n",
|
329 | 6dbe553f | Jan Kiszka | inet_ntoa(dst_addr), ntohs(dst_port), |
330 | 6dbe553f | Jan Kiszka | so->so_rcv.sb_cc, so->so_snd.sb_cc); |
331 | 6dbe553f | Jan Kiszka | } |
332 | e6d43cfb | Jan Kiszka | |
333 | e6d43cfb | Jan Kiszka | for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
|
334 | f293d8b1 | Alon Levy | snprintf(buf, sizeof(buf), " ICMP[%d sec]", |
335 | e6d43cfb | Jan Kiszka | (so->so_expire - curtime) / 1000);
|
336 | e6d43cfb | Jan Kiszka | src.sin_addr = so->so_laddr; |
337 | e6d43cfb | Jan Kiszka | dst_addr = so->so_faddr; |
338 | f293d8b1 | Alon Levy | monitor_printf(mon, "%-19s %3d %15s - ", buf, so->s,
|
339 | e6d43cfb | Jan Kiszka | src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
|
340 | e6d43cfb | Jan Kiszka | monitor_printf(mon, "%15s - %5d %5d\n", inet_ntoa(dst_addr),
|
341 | e6d43cfb | Jan Kiszka | so->so_rcv.sb_cc, so->so_snd.sb_cc); |
342 | e6d43cfb | Jan Kiszka | } |
343 | 6dbe553f | Jan Kiszka | } |