2130 |
2130 |
}
|
2131 |
2131 |
#endif
|
2132 |
2132 |
|
|
2133 |
/***********************************************************/
|
|
2134 |
/* UDP Net console */
|
|
2135 |
|
|
2136 |
typedef struct {
|
|
2137 |
IOCanRWHandler *fd_can_read;
|
|
2138 |
IOReadHandler *fd_read;
|
|
2139 |
void *fd_opaque;
|
|
2140 |
int fd;
|
|
2141 |
struct sockaddr_in daddr;
|
|
2142 |
char buf[1024];
|
|
2143 |
int bufcnt;
|
|
2144 |
int bufptr;
|
|
2145 |
int max_size;
|
|
2146 |
} NetCharDriver;
|
|
2147 |
|
|
2148 |
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
|
2149 |
{
|
|
2150 |
NetCharDriver *s = chr->opaque;
|
|
2151 |
|
|
2152 |
return sendto(s->fd, buf, len, 0,
|
|
2153 |
(struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
|
|
2154 |
}
|
|
2155 |
|
|
2156 |
static int udp_chr_read_poll(void *opaque)
|
|
2157 |
{
|
|
2158 |
CharDriverState *chr = opaque;
|
|
2159 |
NetCharDriver *s = chr->opaque;
|
|
2160 |
|
|
2161 |
s->max_size = s->fd_can_read(s->fd_opaque);
|
|
2162 |
|
|
2163 |
/* If there were any stray characters in the queue process them
|
|
2164 |
* first
|
|
2165 |
*/
|
|
2166 |
while (s->max_size > 0 && s->bufptr < s->bufcnt) {
|
|
2167 |
s->fd_read(s->fd_opaque, &s->buf[s->bufptr], 1);
|
|
2168 |
s->bufptr++;
|
|
2169 |
s->max_size = s->fd_can_read(s->fd_opaque);
|
|
2170 |
}
|
|
2171 |
return s->max_size;
|
|
2172 |
}
|
|
2173 |
|
|
2174 |
static void udp_chr_read(void *opaque)
|
|
2175 |
{
|
|
2176 |
CharDriverState *chr = opaque;
|
|
2177 |
NetCharDriver *s = chr->opaque;
|
|
2178 |
|
|
2179 |
if (s->max_size == 0)
|
|
2180 |
return;
|
|
2181 |
s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
|
|
2182 |
s->bufptr = s->bufcnt;
|
|
2183 |
if (s->bufcnt <= 0)
|
|
2184 |
return;
|
|
2185 |
|
|
2186 |
s->bufptr = 0;
|
|
2187 |
while (s->max_size > 0 && s->bufptr < s->bufcnt) {
|
|
2188 |
s->fd_read(s->fd_opaque, &s->buf[s->bufptr], 1);
|
|
2189 |
s->bufptr++;
|
|
2190 |
s->max_size = s->fd_can_read(s->fd_opaque);
|
|
2191 |
}
|
|
2192 |
}
|
|
2193 |
|
|
2194 |
static void udp_chr_add_read_handler(CharDriverState *chr,
|
|
2195 |
IOCanRWHandler *fd_can_read,
|
|
2196 |
IOReadHandler *fd_read, void *opaque)
|
|
2197 |
{
|
|
2198 |
NetCharDriver *s = chr->opaque;
|
|
2199 |
|
|
2200 |
if (s->fd >= 0) {
|
|
2201 |
s->fd_can_read = fd_can_read;
|
|
2202 |
s->fd_read = fd_read;
|
|
2203 |
s->fd_opaque = opaque;
|
|
2204 |
qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
|
|
2205 |
udp_chr_read, NULL, chr);
|
|
2206 |
}
|
|
2207 |
}
|
|
2208 |
|
|
2209 |
int parse_host_port(struct sockaddr_in *saddr, const char *str);
|
|
2210 |
|
|
2211 |
CharDriverState *qemu_chr_open_udp(const char *def)
|
|
2212 |
{
|
|
2213 |
CharDriverState *chr = NULL;
|
|
2214 |
NetCharDriver *s = NULL;
|
|
2215 |
int fd = -1;
|
|
2216 |
int con_type;
|
|
2217 |
struct sockaddr_in addr;
|
|
2218 |
const char *p, *r;
|
|
2219 |
int port;
|
|
2220 |
|
|
2221 |
chr = qemu_mallocz(sizeof(CharDriverState));
|
|
2222 |
if (!chr)
|
|
2223 |
goto return_err;
|
|
2224 |
s = qemu_mallocz(sizeof(NetCharDriver));
|
|
2225 |
if (!s)
|
|
2226 |
goto return_err;
|
|
2227 |
|
|
2228 |
fd = socket(PF_INET, SOCK_DGRAM, 0);
|
|
2229 |
if (fd < 0) {
|
|
2230 |
perror("socket(PF_INET, SOCK_DGRAM)");
|
|
2231 |
goto return_err;
|
|
2232 |
}
|
|
2233 |
|
|
2234 |
/* There are three types of port definitions
|
|
2235 |
* 1) udp:remote_port
|
|
2236 |
* Juse use 0.0.0.0 for the IP and send to remote
|
|
2237 |
* 2) udp:remote_host:port
|
|
2238 |
* Use a IP and send traffic to remote
|
|
2239 |
* 3) udp:local_port:remote_host:remote_port
|
|
2240 |
* Use local_port as the originator + #2
|
|
2241 |
*/
|
|
2242 |
con_type = 0;
|
|
2243 |
p = def;
|
|
2244 |
while ((p = strchr(p, ':'))) {
|
|
2245 |
p++;
|
|
2246 |
con_type++;
|
|
2247 |
}
|
|
2248 |
|
|
2249 |
p = def;
|
|
2250 |
memset(&addr,0,sizeof(addr));
|
|
2251 |
addr.sin_family = AF_INET;
|
|
2252 |
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
2253 |
s->daddr.sin_family = AF_INET;
|
|
2254 |
s->daddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
2255 |
|
|
2256 |
switch (con_type) {
|
|
2257 |
case 0:
|
|
2258 |
port = strtol(p, (char **)&r, 0);
|
|
2259 |
if (r == p) {
|
|
2260 |
fprintf(stderr, "Error parsing port number\n");
|
|
2261 |
goto return_err;
|
|
2262 |
}
|
|
2263 |
s->daddr.sin_port = htons((short)port);
|
|
2264 |
break;
|
|
2265 |
case 2:
|
|
2266 |
port = strtol(p, (char **)&r, 0);
|
|
2267 |
if (r == p) {
|
|
2268 |
fprintf(stderr, "Error parsing port number\n");
|
|
2269 |
goto return_err;
|
|
2270 |
}
|
|
2271 |
addr.sin_port = htons((short)port);
|
|
2272 |
p = r + 1;
|
|
2273 |
/* Fall through to case 1 now that we have the local port */
|
|
2274 |
case 1:
|
|
2275 |
if (parse_host_port(&s->daddr, p) < 0) {
|
|
2276 |
fprintf(stderr, "Error parsing host name and port\n");
|
|
2277 |
goto return_err;
|
|
2278 |
}
|
|
2279 |
break;
|
|
2280 |
default:
|
|
2281 |
fprintf(stderr, "Too many ':' characters\n");
|
|
2282 |
goto return_err;
|
|
2283 |
}
|
|
2284 |
|
|
2285 |
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
|
2286 |
{
|
|
2287 |
perror("bind");
|
|
2288 |
goto return_err;
|
|
2289 |
}
|
|
2290 |
|
|
2291 |
s->fd = fd;
|
|
2292 |
s->bufcnt = 0;
|
|
2293 |
s->bufptr = 0;
|
|
2294 |
chr->opaque = s;
|
|
2295 |
chr->chr_write = udp_chr_write;
|
|
2296 |
chr->chr_add_read_handler = udp_chr_add_read_handler;
|
|
2297 |
return chr;
|
|
2298 |
|
|
2299 |
return_err:
|
|
2300 |
if (chr)
|
|
2301 |
free(chr);
|
|
2302 |
if (s)
|
|
2303 |
free(s);
|
|
2304 |
if (fd >= 0)
|
|
2305 |
closesocket(fd);
|
|
2306 |
return NULL;
|
|
2307 |
}
|
|
2308 |
|
|
2309 |
/***********************************************************/
|
|
2310 |
/* TCP Net console */
|
|
2311 |
|
|
2312 |
typedef struct {
|
|
2313 |
IOCanRWHandler *fd_can_read;
|
|
2314 |
IOReadHandler *fd_read;
|
|
2315 |
void *fd_opaque;
|
|
2316 |
int fd, listen_fd;
|
|
2317 |
int connected;
|
|
2318 |
int max_size;
|
|
2319 |
} TCPCharDriver;
|
|
2320 |
|
|
2321 |
static void tcp_chr_accept(void *opaque);
|
|
2322 |
|
|
2323 |
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
|
2324 |
{
|
|
2325 |
TCPCharDriver *s = chr->opaque;
|
|
2326 |
if (s->connected) {
|
|
2327 |
return send_all(s->fd, buf, len);
|
|
2328 |
} else {
|
|
2329 |
/* XXX: indicate an error ? */
|
|
2330 |
return len;
|
|
2331 |
}
|
|
2332 |
}
|
|
2333 |
|
|
2334 |
static int tcp_chr_read_poll(void *opaque)
|
|
2335 |
{
|
|
2336 |
CharDriverState *chr = opaque;
|
|
2337 |
TCPCharDriver *s = chr->opaque;
|
|
2338 |
if (!s->connected)
|
|
2339 |
return 0;
|
|
2340 |
s->max_size = s->fd_can_read(s->fd_opaque);
|
|
2341 |
return s->max_size;
|
|
2342 |
}
|
|
2343 |
|
|
2344 |
static void tcp_chr_read(void *opaque)
|
|
2345 |
{
|
|
2346 |
CharDriverState *chr = opaque;
|
|
2347 |
TCPCharDriver *s = chr->opaque;
|
|
2348 |
uint8_t buf[1024];
|
|
2349 |
int len, size;
|
|
2350 |
|
|
2351 |
if (!s->connected || s->max_size <= 0)
|
|
2352 |
return;
|
|
2353 |
len = sizeof(buf);
|
|
2354 |
if (len > s->max_size)
|
|
2355 |
len = s->max_size;
|
|
2356 |
size = recv(s->fd, buf, len, 0);
|
|
2357 |
if (size == 0) {
|
|
2358 |
/* connection closed */
|
|
2359 |
s->connected = 0;
|
|
2360 |
if (s->listen_fd >= 0) {
|
|
2361 |
qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
|
|
2362 |
}
|
|
2363 |
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
|
|
2364 |
closesocket(s->fd);
|
|
2365 |
s->fd = -1;
|
|
2366 |
} else if (size > 0) {
|
|
2367 |
s->fd_read(s->fd_opaque, buf, size);
|
|
2368 |
}
|
|
2369 |
}
|
|
2370 |
|
|
2371 |
static void tcp_chr_add_read_handler(CharDriverState *chr,
|
|
2372 |
IOCanRWHandler *fd_can_read,
|
|
2373 |
IOReadHandler *fd_read, void *opaque)
|
|
2374 |
{
|
|
2375 |
TCPCharDriver *s = chr->opaque;
|
|
2376 |
|
|
2377 |
s->fd_can_read = fd_can_read;
|
|
2378 |
s->fd_read = fd_read;
|
|
2379 |
s->fd_opaque = opaque;
|
|
2380 |
}
|
|
2381 |
|
|
2382 |
static void tcp_chr_connect(void *opaque)
|
|
2383 |
{
|
|
2384 |
CharDriverState *chr = opaque;
|
|
2385 |
TCPCharDriver *s = chr->opaque;
|
|
2386 |
|
|
2387 |
s->connected = 1;
|
|
2388 |
qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
|
|
2389 |
tcp_chr_read, NULL, chr);
|
|
2390 |
}
|
|
2391 |
|
|
2392 |
static void tcp_chr_accept(void *opaque)
|
|
2393 |
{
|
|
2394 |
CharDriverState *chr = opaque;
|
|
2395 |
TCPCharDriver *s = chr->opaque;
|
|
2396 |
struct sockaddr_in saddr;
|
|
2397 |
socklen_t len;
|
|
2398 |
int fd;
|
|
2399 |
|
|
2400 |
for(;;) {
|
|
2401 |
len = sizeof(saddr);
|
|
2402 |
fd = accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
|
|
2403 |
if (fd < 0 && errno != EINTR) {
|
|
2404 |
return;
|
|
2405 |
} else if (fd >= 0) {
|
|
2406 |
break;
|
|
2407 |
}
|
|
2408 |
}
|
|
2409 |
socket_set_nonblock(fd);
|
|
2410 |
s->fd = fd;
|
|
2411 |
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
|
|
2412 |
tcp_chr_connect(chr);
|
|
2413 |
}
|
|
2414 |
|
|
2415 |
static void tcp_chr_close(CharDriverState *chr)
|
|
2416 |
{
|
|
2417 |
TCPCharDriver *s = chr->opaque;
|
|
2418 |
if (s->fd >= 0)
|
|
2419 |
closesocket(s->fd);
|
|
2420 |
if (s->listen_fd >= 0)
|
|
2421 |
closesocket(s->listen_fd);
|
|
2422 |
qemu_free(s);
|
|
2423 |
}
|
|
2424 |
|
|
2425 |
static CharDriverState *qemu_chr_open_tcp(const char *host_str,
|
|
2426 |
int is_listen)
|
|
2427 |
{
|
|
2428 |
CharDriverState *chr = NULL;
|
|
2429 |
TCPCharDriver *s = NULL;
|
|
2430 |
int fd = -1, ret, err, val;
|
|
2431 |
struct sockaddr_in saddr;
|
|
2432 |
|
|
2433 |
if (parse_host_port(&saddr, host_str) < 0)
|
|
2434 |
goto fail;
|
|
2435 |
|
|
2436 |
chr = qemu_mallocz(sizeof(CharDriverState));
|
|
2437 |
if (!chr)
|
|
2438 |
goto fail;
|
|
2439 |
s = qemu_mallocz(sizeof(TCPCharDriver));
|
|
2440 |
if (!s)
|
|
2441 |
goto fail;
|
|
2442 |
|
|
2443 |
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
2444 |
if (fd < 0)
|
|
2445 |
goto fail;
|
|
2446 |
socket_set_nonblock(fd);
|
|
2447 |
|
|
2448 |
s->connected = 0;
|
|
2449 |
s->fd = -1;
|
|
2450 |
s->listen_fd = -1;
|
|
2451 |
if (is_listen) {
|
|
2452 |
/* allow fast reuse */
|
|
2453 |
val = 1;
|
|
2454 |
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
|
|
2455 |
|
|
2456 |
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
|
2457 |
if (ret < 0)
|
|
2458 |
goto fail;
|
|
2459 |
ret = listen(fd, 0);
|
|
2460 |
if (ret < 0)
|
|
2461 |
goto fail;
|
|
2462 |
s->listen_fd = fd;
|
|
2463 |
qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
|
|
2464 |
} else {
|
|
2465 |
for(;;) {
|
|
2466 |
ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
|
|
2467 |
if (ret < 0) {
|
|
2468 |
err = socket_error();
|
|
2469 |
if (err == EINTR || err == EWOULDBLOCK) {
|
|
2470 |
} else if (err == EINPROGRESS) {
|
|
2471 |
break;
|
|
2472 |
} else {
|
|
2473 |
goto fail;
|
|
2474 |
}
|
|
2475 |
} else {
|
|
2476 |
s->connected = 1;
|
|
2477 |
break;
|
|
2478 |
}
|
|
2479 |
}
|
|
2480 |
s->fd = fd;
|
|
2481 |
if (s->connected)
|
|
2482 |
tcp_chr_connect(chr);
|
|
2483 |
else
|
|
2484 |
qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
|
|
2485 |
}
|
|
2486 |
|
|
2487 |
chr->opaque = s;
|
|
2488 |
chr->chr_write = tcp_chr_write;
|
|
2489 |
chr->chr_add_read_handler = tcp_chr_add_read_handler;
|
|
2490 |
chr->chr_close = tcp_chr_close;
|
|
2491 |
return chr;
|
|
2492 |
fail:
|
|
2493 |
if (fd >= 0)
|
|
2494 |
closesocket(fd);
|
|
2495 |
qemu_free(s);
|
|
2496 |
qemu_free(chr);
|
|
2497 |
return NULL;
|
|
2498 |
}
|
|
2499 |
|
2133 |
2500 |
CharDriverState *qemu_chr_open(const char *filename)
|
2134 |
2501 |
{
|
2135 |
2502 |
const char *p;
|
... | ... | |
2139 |
2506 |
} else if (!strcmp(filename, "null")) {
|
2140 |
2507 |
return qemu_chr_open_null();
|
2141 |
2508 |
} else
|
|
2509 |
if (strstart(filename, "tcp:", &p)) {
|
|
2510 |
return qemu_chr_open_tcp(p, 0);
|
|
2511 |
} else
|
|
2512 |
if (strstart(filename, "tcpl:", &p)) {
|
|
2513 |
return qemu_chr_open_tcp(p, 1);
|
|
2514 |
} else
|
|
2515 |
if (strstart(filename, "udp:", &p)) {
|
|
2516 |
return qemu_chr_open_udp(p);
|
|
2517 |
} else
|
2142 |
2518 |
#ifndef _WIN32
|
2143 |
2519 |
if (strstart(filename, "file:", &p)) {
|
2144 |
2520 |
return qemu_chr_open_file_out(p);
|
... | ... | |
2844 |
3220 |
socket_set_nonblock(fd);
|
2845 |
3221 |
return fd;
|
2846 |
3222 |
fail:
|
2847 |
|
if (fd>=0) close(fd);
|
|
3223 |
if (fd >= 0)
|
|
3224 |
closesocket(fd);
|
2848 |
3225 |
return -1;
|
2849 |
3226 |
}
|
2850 |
3227 |
|
... | ... | |
2972 |
3349 |
}
|
2973 |
3350 |
s1 = net_socket_fd_init(s->vlan, fd, 1);
|
2974 |
3351 |
if (!s1) {
|
2975 |
|
close(fd);
|
|
3352 |
closesocket(fd);
|
2976 |
3353 |
} else {
|
2977 |
3354 |
snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
|
2978 |
3355 |
"socket: connection from %s:%d",
|