slirp: remove now useless QEMU headers inclusions
[qemu/ar7.git] / slirp / misc.c
bloba77cc34b30587fbf7a4294ede84419fbc6921cac
1 /*
2 * Copyright (c) 1995 Danny Gasparovski.
4 * Please read the file COPYRIGHT for the
5 * terms and conditions of the copyright.
6 */
8 #include "qemu/osdep.h"
9 #include "slirp.h"
10 #include "libslirp.h"
12 inline void
13 insque(void *a, void *b)
15 register struct quehead *element = (struct quehead *) a;
16 register struct quehead *head = (struct quehead *) b;
17 element->qh_link = head->qh_link;
18 head->qh_link = (struct quehead *)element;
19 element->qh_rlink = (struct quehead *)head;
20 ((struct quehead *)(element->qh_link))->qh_rlink
21 = (struct quehead *)element;
24 inline void
25 remque(void *a)
27 register struct quehead *element = (struct quehead *) a;
28 ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
29 ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
30 element->qh_rlink = NULL;
33 struct gfwd_list *
34 add_guestfwd(struct gfwd_list **ex_ptr,
35 SlirpWriteCb write_cb, void *opaque,
36 struct in_addr addr, int port)
38 struct gfwd_list *f = g_new0(struct gfwd_list, 1);
40 f->write_cb = write_cb;
41 f->opaque = opaque;
42 f->ex_fport = port;
43 f->ex_addr = addr;
44 f->ex_next = *ex_ptr;
45 *ex_ptr = f;
47 return f;
50 struct gfwd_list *
51 add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
52 struct in_addr addr, int port)
54 struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
56 f->ex_exec = g_strdup(cmdline);
58 return f;
61 static int
62 slirp_socketpair_with_oob(int sv[2])
64 struct sockaddr_in addr = {
65 .sin_family = AF_INET,
66 .sin_port = 0,
67 .sin_addr.s_addr = INADDR_ANY,
69 socklen_t addrlen = sizeof(addr);
70 int ret, s;
72 sv[1] = -1;
73 s = slirp_socket(AF_INET, SOCK_STREAM, 0);
74 if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
75 listen(s, 1) < 0 ||
76 getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
77 goto err;
80 sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0);
81 if (sv[1] < 0) {
82 goto err;
85 * This connect won't block because we've already listen()ed on
86 * the server end (even though we won't accept() the connection
87 * until later on).
89 do {
90 ret = connect(sv[1], (struct sockaddr *)&addr, addrlen);
91 } while (ret < 0 && errno == EINTR);
92 if (ret < 0) {
93 goto err;
96 do {
97 sv[0] = accept(s, (struct sockaddr *)&addr, &addrlen);
98 } while (sv[0] < 0 && errno == EINTR);
99 if (sv[0] < 0) {
100 goto err;
103 slirp_closesocket(s);
104 return 0;
106 err:
107 g_critical("slirp_socketpair(): %s", strerror(errno));
108 if (s >= 0) {
109 slirp_closesocket(s);
111 if (sv[1] >= 0) {
112 slirp_closesocket(sv[1]);
114 return -1;
117 static void
118 fork_exec_child_setup(gpointer data)
120 #ifndef _WIN32
121 setsid();
122 #endif
126 fork_exec(struct socket *so, const char *ex)
128 GError *err = NULL;
129 char **argv;
130 int opt, sp[2];
132 DEBUG_CALL("fork_exec");
133 DEBUG_ARG("so = %p", so);
134 DEBUG_ARG("ex = %p", ex);
136 if (slirp_socketpair_with_oob(sp) < 0) {
137 return 0;
140 argv = g_strsplit(ex, " ", -1);
141 g_spawn_async_with_fds(NULL /* cwd */,
142 argv,
143 NULL /* env */,
144 G_SPAWN_SEARCH_PATH,
145 fork_exec_child_setup, NULL /* data */,
146 NULL /* child_pid */,
147 sp[1], sp[1], sp[1],
148 &err);
149 g_strfreev(argv);
151 if (err) {
152 g_critical("fork_exec: %s", err->message);
153 g_error_free(err);
154 slirp_closesocket(sp[0]);
155 slirp_closesocket(sp[1]);
156 return 0;
159 so->s = sp[0];
160 slirp_closesocket(sp[1]);
161 slirp_socket_set_fast_reuse(so->s);
162 opt = 1;
163 slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
164 slirp_set_nonblock(so->s);
165 so->slirp->cb->register_poll_fd(so->s);
166 return 1;
169 char *slirp_connection_info(Slirp *slirp)
171 GString *str = g_string_new(NULL);
172 const char * const tcpstates[] = {
173 [TCPS_CLOSED] = "CLOSED",
174 [TCPS_LISTEN] = "LISTEN",
175 [TCPS_SYN_SENT] = "SYN_SENT",
176 [TCPS_SYN_RECEIVED] = "SYN_RCVD",
177 [TCPS_ESTABLISHED] = "ESTABLISHED",
178 [TCPS_CLOSE_WAIT] = "CLOSE_WAIT",
179 [TCPS_FIN_WAIT_1] = "FIN_WAIT_1",
180 [TCPS_CLOSING] = "CLOSING",
181 [TCPS_LAST_ACK] = "LAST_ACK",
182 [TCPS_FIN_WAIT_2] = "FIN_WAIT_2",
183 [TCPS_TIME_WAIT] = "TIME_WAIT",
185 struct in_addr dst_addr;
186 struct sockaddr_in src;
187 socklen_t src_len;
188 uint16_t dst_port;
189 struct socket *so;
190 const char *state;
191 char buf[20];
193 g_string_append_printf(str,
194 " Protocol[State] FD Source Address Port "
195 "Dest. Address Port RecvQ SendQ\n");
197 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
198 if (so->so_state & SS_HOSTFWD) {
199 state = "HOST_FORWARD";
200 } else if (so->so_tcpcb) {
201 state = tcpstates[so->so_tcpcb->t_state];
202 } else {
203 state = "NONE";
205 if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
206 src_len = sizeof(src);
207 getsockname(so->s, (struct sockaddr *)&src, &src_len);
208 dst_addr = so->so_laddr;
209 dst_port = so->so_lport;
210 } else {
211 src.sin_addr = so->so_laddr;
212 src.sin_port = so->so_lport;
213 dst_addr = so->so_faddr;
214 dst_port = so->so_fport;
216 snprintf(buf, sizeof(buf), " TCP[%s]", state);
217 g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
218 src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
219 ntohs(src.sin_port));
220 g_string_append_printf(str, "%15s %5d %5d %5d\n",
221 inet_ntoa(dst_addr), ntohs(dst_port),
222 so->so_rcv.sb_cc, so->so_snd.sb_cc);
225 for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
226 if (so->so_state & SS_HOSTFWD) {
227 snprintf(buf, sizeof(buf), " UDP[HOST_FORWARD]");
228 src_len = sizeof(src);
229 getsockname(so->s, (struct sockaddr *)&src, &src_len);
230 dst_addr = so->so_laddr;
231 dst_port = so->so_lport;
232 } else {
233 snprintf(buf, sizeof(buf), " UDP[%d sec]",
234 (so->so_expire - curtime) / 1000);
235 src.sin_addr = so->so_laddr;
236 src.sin_port = so->so_lport;
237 dst_addr = so->so_faddr;
238 dst_port = so->so_fport;
240 g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
241 src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
242 ntohs(src.sin_port));
243 g_string_append_printf(str, "%15s %5d %5d %5d\n",
244 inet_ntoa(dst_addr), ntohs(dst_port),
245 so->so_rcv.sb_cc, so->so_snd.sb_cc);
248 for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
249 snprintf(buf, sizeof(buf), " ICMP[%d sec]",
250 (so->so_expire - curtime) / 1000);
251 src.sin_addr = so->so_laddr;
252 dst_addr = so->so_faddr;
253 g_string_append_printf(str, "%-19s %3d %15s - ", buf, so->s,
254 src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
255 g_string_append_printf(str, "%15s - %5d %5d\n", inet_ntoa(dst_addr),
256 so->so_rcv.sb_cc, so->so_snd.sb_cc);
259 return g_string_free(str, FALSE);