]> git.proxmox.com Git - mirror_qemu.git/blame - net.c
Make net_client_init() consume slirp_configs even on error
[mirror_qemu.git] / net.c
CommitLineData
63a01ef8
AL
1/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
63a01ef8
AL
24#include <unistd.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
28#include <errno.h>
29#include <sys/time.h>
30#include <zlib.h>
31
71e72a19 32/* Needed early for CONFIG_BSD etc. */
d40cdb10
BS
33#include "config-host.h"
34
63a01ef8
AL
35#ifndef _WIN32
36#include <sys/times.h>
37#include <sys/wait.h>
38#include <termios.h>
39#include <sys/mman.h>
40#include <sys/ioctl.h>
24646c7e 41#include <sys/resource.h>
63a01ef8
AL
42#include <sys/socket.h>
43#include <netinet/in.h>
24646c7e
BS
44#include <net/if.h>
45#ifdef __NetBSD__
46#include <net/if_tap.h>
47#endif
48#ifdef __linux__
49#include <linux/if_tun.h>
50#endif
51#include <arpa/inet.h>
63a01ef8
AL
52#include <dirent.h>
53#include <netdb.h>
54#include <sys/select.h>
71e72a19 55#ifdef CONFIG_BSD
63a01ef8 56#include <sys/stat.h>
c5e97233 57#if defined(__FreeBSD__) || defined(__DragonFly__)
63a01ef8 58#include <libutil.h>
24646c7e
BS
59#else
60#include <util.h>
63a01ef8
AL
61#endif
62#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
63#include <freebsd/stdlib.h>
64#else
65#ifdef __linux__
63a01ef8
AL
66#include <pty.h>
67#include <malloc.h>
68#include <linux/rtc.h>
69
70/* For the benefit of older linux systems which don't supply it,
71 we use a local copy of hpet.h. */
72/* #include <linux/hpet.h> */
73#include "hpet.h"
74
75#include <linux/ppdev.h>
76#include <linux/parport.h>
77#endif
78#ifdef __sun__
79#include <sys/stat.h>
80#include <sys/ethernet.h>
81#include <sys/sockio.h>
82#include <netinet/arp.h>
83#include <netinet/in.h>
84#include <netinet/in_systm.h>
85#include <netinet/ip.h>
86#include <netinet/ip_icmp.h> // must come after ip.h
87#include <netinet/udp.h>
88#include <netinet/tcp.h>
89#include <net/if.h>
90#include <syslog.h>
91#include <stropts.h>
92#endif
93#endif
94#endif
95
63a01ef8
AL
96#if defined(__OpenBSD__)
97#include <util.h>
98#endif
99
100#if defined(CONFIG_VDE)
101#include <libvdeplug.h>
102#endif
103
511d2b14
BS
104#include "qemu-common.h"
105#include "net.h"
106#include "monitor.h"
107#include "sysemu.h"
108#include "qemu-timer.h"
109#include "qemu-char.h"
110#include "audio/audio.h"
111#include "qemu_socket.h"
bb9ea79e 112#include "qemu-log.h"
511d2b14 113
d918f23e 114#include "slirp/libslirp.h"
72cf2d4f 115#include "qemu-queue.h"
511d2b14
BS
116
117
63a01ef8
AL
118static VLANState *first_vlan;
119
120/***********************************************************/
121/* network device redirectors */
122
123#if defined(DEBUG_NET) || defined(DEBUG_SLIRP)
124static void hex_dump(FILE *f, const uint8_t *buf, int size)
125{
126 int len, i, j, c;
127
128 for(i=0;i<size;i+=16) {
129 len = size - i;
130 if (len > 16)
131 len = 16;
132 fprintf(f, "%08x ", i);
133 for(j=0;j<16;j++) {
134 if (j < len)
135 fprintf(f, " %02x", buf[i+j]);
136 else
137 fprintf(f, " ");
138 }
139 fprintf(f, " ");
140 for(j=0;j<len;j++) {
141 c = buf[i+j];
142 if (c < ' ' || c > '~')
143 c = '.';
144 fprintf(f, "%c", c);
145 }
146 fprintf(f, "\n");
147 }
148}
149#endif
150
151static int parse_macaddr(uint8_t *macaddr, const char *p)
152{
153 int i;
154 char *last_char;
155 long int offset;
156
157 errno = 0;
158 offset = strtol(p, &last_char, 0);
159 if (0 == errno && '\0' == *last_char &&
160 offset >= 0 && offset <= 0xFFFFFF) {
161 macaddr[3] = (offset & 0xFF0000) >> 16;
162 macaddr[4] = (offset & 0xFF00) >> 8;
163 macaddr[5] = offset & 0xFF;
164 return 0;
165 } else {
166 for(i = 0; i < 6; i++) {
167 macaddr[i] = strtol(p, (char **)&p, 16);
168 if (i == 5) {
169 if (*p != '\0')
170 return -1;
171 } else {
172 if (*p != ':' && *p != '-')
173 return -1;
174 p++;
175 }
176 }
177 return 0;
178 }
179
180 return -1;
181}
182
183static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
184{
185 const char *p, *p1;
186 int len;
187 p = *pp;
188 p1 = strchr(p, sep);
189 if (!p1)
190 return -1;
191 len = p1 - p;
192 p1++;
193 if (buf_size > 0) {
194 if (len > buf_size - 1)
195 len = buf_size - 1;
196 memcpy(buf, p, len);
197 buf[len] = '\0';
198 }
199 *pp = p1;
200 return 0;
201}
202
203int parse_host_src_port(struct sockaddr_in *haddr,
204 struct sockaddr_in *saddr,
205 const char *input_str)
206{
207 char *str = strdup(input_str);
208 char *host_str = str;
209 char *src_str;
210 const char *src_str2;
211 char *ptr;
212
213 /*
214 * Chop off any extra arguments at the end of the string which
215 * would start with a comma, then fill in the src port information
216 * if it was provided else use the "any address" and "any port".
217 */
218 if ((ptr = strchr(str,',')))
219 *ptr = '\0';
220
221 if ((src_str = strchr(input_str,'@'))) {
222 *src_str = '\0';
223 src_str++;
224 }
225
226 if (parse_host_port(haddr, host_str) < 0)
227 goto fail;
228
229 src_str2 = src_str;
230 if (!src_str || *src_str == '\0')
231 src_str2 = ":0";
232
233 if (parse_host_port(saddr, src_str2) < 0)
234 goto fail;
235
236 free(str);
237 return(0);
238
239fail:
240 free(str);
241 return -1;
242}
243
244int parse_host_port(struct sockaddr_in *saddr, const char *str)
245{
246 char buf[512];
247 struct hostent *he;
248 const char *p, *r;
249 int port;
250
251 p = str;
252 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
253 return -1;
254 saddr->sin_family = AF_INET;
255 if (buf[0] == '\0') {
256 saddr->sin_addr.s_addr = 0;
257 } else {
cd390083 258 if (qemu_isdigit(buf[0])) {
63a01ef8
AL
259 if (!inet_aton(buf, &saddr->sin_addr))
260 return -1;
261 } else {
262 if ((he = gethostbyname(buf)) == NULL)
263 return - 1;
264 saddr->sin_addr = *(struct in_addr *)he->h_addr;
265 }
266 }
267 port = strtol(p, (char **)&r, 0);
268 if (r == p)
269 return -1;
270 saddr->sin_port = htons(port);
271 return 0;
272}
273
7cb7434b
AL
274void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6])
275{
276 snprintf(vc->info_str, sizeof(vc->info_str),
4dda4063
AL
277 "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
278 vc->model,
7cb7434b
AL
279 macaddr[0], macaddr[1], macaddr[2],
280 macaddr[3], macaddr[4], macaddr[5]);
281}
282
676cff29
AL
283static char *assign_name(VLANClientState *vc1, const char *model)
284{
285 VLANState *vlan;
286 char buf[256];
287 int id = 0;
288
289 for (vlan = first_vlan; vlan; vlan = vlan->next) {
290 VLANClientState *vc;
291
292 for (vc = vlan->first_client; vc; vc = vc->next)
293 if (vc != vc1 && strcmp(vc->model, model) == 0)
294 id++;
295 }
296
297 snprintf(buf, sizeof(buf), "%s.%d", model, id);
298
02374aa0 299 return qemu_strdup(buf);
676cff29
AL
300}
301
63a01ef8 302VLANClientState *qemu_new_vlan_client(VLANState *vlan,
bf38c1a0 303 const char *model,
7a9f6e4a 304 const char *name,
cda9046b
MM
305 NetCanReceive *can_receive,
306 NetReceive *receive,
307 NetReceiveIOV *receive_iov,
b946a153 308 NetCleanup *cleanup,
63a01ef8
AL
309 void *opaque)
310{
311 VLANClientState *vc, **pvc;
312 vc = qemu_mallocz(sizeof(VLANClientState));
02374aa0 313 vc->model = qemu_strdup(model);
7a9f6e4a 314 if (name)
02374aa0 315 vc->name = qemu_strdup(name);
7a9f6e4a
AL
316 else
317 vc->name = assign_name(vc, model);
cda9046b
MM
318 vc->can_receive = can_receive;
319 vc->receive = receive;
320 vc->receive_iov = receive_iov;
b946a153 321 vc->cleanup = cleanup;
63a01ef8
AL
322 vc->opaque = opaque;
323 vc->vlan = vlan;
324
325 vc->next = NULL;
326 pvc = &vlan->first_client;
327 while (*pvc != NULL)
328 pvc = &(*pvc)->next;
329 *pvc = vc;
330 return vc;
331}
332
333void qemu_del_vlan_client(VLANClientState *vc)
334{
335 VLANClientState **pvc = &vc->vlan->first_client;
336
337 while (*pvc != NULL)
338 if (*pvc == vc) {
339 *pvc = vc->next;
b946a153
AL
340 if (vc->cleanup) {
341 vc->cleanup(vc);
342 }
02374aa0
MM
343 qemu_free(vc->name);
344 qemu_free(vc->model);
dad35419 345 qemu_free(vc);
63a01ef8
AL
346 break;
347 } else
348 pvc = &(*pvc)->next;
349}
350
8b13c4a7
AL
351VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque)
352{
353 VLANClientState **pvc = &vlan->first_client;
354
355 while (*pvc != NULL)
356 if ((*pvc)->opaque == opaque)
357 return *pvc;
358 else
359 pvc = &(*pvc)->next;
360
361 return NULL;
362}
363
1a609520
JK
364static VLANClientState *
365qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
366 const char *client_str)
367{
368 VLANState *vlan;
369 VLANClientState *vc;
370
371 vlan = qemu_find_vlan(vlan_id, 0);
372 if (!vlan) {
373 monitor_printf(mon, "unknown VLAN %d\n", vlan_id);
374 return NULL;
375 }
376
377 for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
378 if (!strcmp(vc->name, client_str)) {
379 break;
380 }
381 }
382 if (!vc) {
383 monitor_printf(mon, "can't find device %s on VLAN %d\n",
384 client_str, vlan_id);
385 }
386
387 return vc;
388}
389
2e1e0641 390int qemu_can_send_packet(VLANClientState *sender)
63a01ef8 391{
2e1e0641 392 VLANState *vlan = sender->vlan;
63a01ef8
AL
393 VLANClientState *vc;
394
2e1e0641
MM
395 for (vc = vlan->first_client; vc != NULL; vc = vc->next) {
396 if (vc == sender) {
397 continue;
398 }
399
cda9046b 400 /* no can_receive() handler, they can always receive */
e3f5ec2b 401 if (!vc->can_receive || vc->can_receive(vc)) {
2e1e0641 402 return 1;
63a01ef8
AL
403 }
404 }
405 return 0;
406}
407
3e021d40 408static int
764a4d1d 409qemu_deliver_packet(VLANClientState *sender, const uint8_t *buf, int size)
63a01ef8 410{
63a01ef8 411 VLANClientState *vc;
3e021d40 412 int ret = -1;
63a01ef8 413
e94667b9
MM
414 sender->vlan->delivering = 1;
415
764a4d1d 416 for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
3e021d40
MM
417 ssize_t len;
418
419 if (vc == sender) {
420 continue;
764a4d1d 421 }
3e021d40
MM
422
423 if (vc->link_down) {
424 ret = size;
425 continue;
426 }
427
428 len = vc->receive(vc, buf, size);
429
430 ret = (ret >= 0) ? ret : len;
764a4d1d 431 }
3e021d40 432
e94667b9
MM
433 sender->vlan->delivering = 0;
434
3e021d40 435 return ret;
764a4d1d
AL
436}
437
8cad5516
MM
438void qemu_purge_queued_packets(VLANClientState *vc)
439{
9da43187 440 VLANPacket *packet, *next;
8cad5516 441
72cf2d4f 442 QTAILQ_FOREACH_SAFE(packet, &vc->vlan->send_queue, entry, next) {
8cad5516 443 if (packet->sender == vc) {
72cf2d4f 444 QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry);
8cad5516 445 qemu_free(packet);
8cad5516
MM
446 }
447 }
448}
449
f3b6c7fc 450void qemu_flush_queued_packets(VLANClientState *vc)
e94667b9 451{
72cf2d4f 452 while (!QTAILQ_EMPTY(&vc->vlan->send_queue)) {
9da43187 453 VLANPacket *packet;
f3b6c7fc
MM
454 int ret;
455
72cf2d4f
BS
456 packet = QTAILQ_FIRST(&vc->vlan->send_queue);
457 QTAILQ_REMOVE(&vc->vlan->send_queue, packet, entry);
f3b6c7fc
MM
458
459 ret = qemu_deliver_packet(packet->sender, packet->data, packet->size);
460 if (ret == 0 && packet->sent_cb != NULL) {
72cf2d4f 461 QTAILQ_INSERT_HEAD(&vc->vlan->send_queue, packet, entry);
f3b6c7fc
MM
462 break;
463 }
464
465 if (packet->sent_cb)
783527a9 466 packet->sent_cb(packet->sender, ret);
f3b6c7fc 467
e94667b9
MM
468 qemu_free(packet);
469 }
470}
471
f3b6c7fc
MM
472static void qemu_enqueue_packet(VLANClientState *sender,
473 const uint8_t *buf, int size,
474 NetPacketSent *sent_cb)
e94667b9
MM
475{
476 VLANPacket *packet;
477
478 packet = qemu_malloc(sizeof(VLANPacket) + size);
e94667b9
MM
479 packet->sender = sender;
480 packet->size = size;
f3b6c7fc 481 packet->sent_cb = sent_cb;
e94667b9 482 memcpy(packet->data, buf, size);
9da43187 483
72cf2d4f 484 QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry);
e94667b9
MM
485}
486
f3b6c7fc
MM
487ssize_t qemu_send_packet_async(VLANClientState *sender,
488 const uint8_t *buf, int size,
489 NetPacketSent *sent_cb)
764a4d1d 490{
f3b6c7fc 491 int ret;
764a4d1d 492
f3b6c7fc
MM
493 if (sender->link_down) {
494 return size;
495 }
436e5e53 496
63a01ef8 497#ifdef DEBUG_NET
f3b6c7fc 498 printf("vlan %d send:\n", sender->vlan->id);
63a01ef8
AL
499 hex_dump(stdout, buf, size);
500#endif
f3b6c7fc
MM
501
502 if (sender->vlan->delivering) {
503 qemu_enqueue_packet(sender, buf, size, NULL);
504 return size;
505 }
506
507 ret = qemu_deliver_packet(sender, buf, size);
508 if (ret == 0 && sent_cb != NULL) {
509 qemu_enqueue_packet(sender, buf, size, sent_cb);
510 return 0;
63a01ef8 511 }
e94667b9 512
f3b6c7fc
MM
513 qemu_flush_queued_packets(sender);
514
515 return ret;
516}
517
518void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
519{
520 qemu_send_packet_async(vc, buf, size, NULL);
63a01ef8
AL
521}
522
fbe78f4f
AL
523static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
524 int iovcnt)
525{
526 uint8_t buffer[4096];
527 size_t offset = 0;
528 int i;
529
530 for (i = 0; i < iovcnt; i++) {
531 size_t len;
532
533 len = MIN(sizeof(buffer) - offset, iov[i].iov_len);
534 memcpy(buffer + offset, iov[i].iov_base, len);
535 offset += len;
536 }
537
f3b6c7fc 538 return vc->receive(vc, buffer, offset);
fbe78f4f
AL
539}
540
e0e7877a
AL
541static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
542{
543 size_t offset = 0;
544 int i;
545
546 for (i = 0; i < iovcnt; i++)
547 offset += iov[i].iov_len;
548 return offset;
549}
550
e94667b9
MM
551static int qemu_deliver_packet_iov(VLANClientState *sender,
552 const struct iovec *iov, int iovcnt)
fbe78f4f 553{
fbe78f4f 554 VLANClientState *vc;
e94667b9
MM
555 int ret = -1;
556
557 sender->vlan->delivering = 1;
558
559 for (vc = sender->vlan->first_client; vc != NULL; vc = vc->next) {
560 ssize_t len;
561
562 if (vc == sender) {
563 continue;
564 }
565
566 if (vc->link_down) {
567 ret = calc_iov_length(iov, iovcnt);
568 continue;
569 }
570
571 if (vc->receive_iov) {
572 len = vc->receive_iov(vc, iov, iovcnt);
573 } else {
574 len = vc_sendv_compat(vc, iov, iovcnt);
575 }
576
577 ret = (ret >= 0) ? ret : len;
578 }
579
580 sender->vlan->delivering = 0;
581
582 return ret;
583}
584
585static ssize_t qemu_enqueue_packet_iov(VLANClientState *sender,
f3b6c7fc
MM
586 const struct iovec *iov, int iovcnt,
587 NetPacketSent *sent_cb)
e94667b9 588{
c27ff608 589 VLANPacket *packet;
e94667b9 590 size_t max_len = 0;
c27ff608 591 int i;
fbe78f4f 592
e94667b9 593 max_len = calc_iov_length(iov, iovcnt);
e0e7877a 594
e94667b9 595 packet = qemu_malloc(sizeof(VLANPacket) + max_len);
e94667b9 596 packet->sender = sender;
f3b6c7fc 597 packet->sent_cb = sent_cb;
e94667b9 598 packet->size = 0;
c27ff608 599
e94667b9
MM
600 for (i = 0; i < iovcnt; i++) {
601 size_t len = iov[i].iov_len;
c27ff608 602
e94667b9
MM
603 memcpy(packet->data + packet->size, iov[i].iov_base, len);
604 packet->size += len;
605 }
fbe78f4f 606
72cf2d4f 607 QTAILQ_INSERT_TAIL(&sender->vlan->send_queue, packet, entry);
fbe78f4f 608
e94667b9
MM
609 return packet->size;
610}
fbe78f4f 611
f3b6c7fc
MM
612ssize_t qemu_sendv_packet_async(VLANClientState *sender,
613 const struct iovec *iov, int iovcnt,
614 NetPacketSent *sent_cb)
e94667b9
MM
615{
616 int ret;
617
618 if (sender->link_down) {
619 return calc_iov_length(iov, iovcnt);
620 }
621
622 if (sender->vlan->delivering) {
f3b6c7fc 623 return qemu_enqueue_packet_iov(sender, iov, iovcnt, NULL);
fbe78f4f
AL
624 }
625
e94667b9 626 ret = qemu_deliver_packet_iov(sender, iov, iovcnt);
f3b6c7fc
MM
627 if (ret == 0 && sent_cb != NULL) {
628 qemu_enqueue_packet_iov(sender, iov, iovcnt, sent_cb);
629 return 0;
630 }
e94667b9
MM
631
632 qemu_flush_queued_packets(sender);
633
634 return ret;
fbe78f4f
AL
635}
636
f3b6c7fc
MM
637ssize_t
638qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt)
639{
640 return qemu_sendv_packet_async(vc, iov, iovcnt, NULL);
641}
642
10ae5a7a
JK
643static void config_error(Monitor *mon, const char *fmt, ...)
644{
645 va_list ap;
646
647 va_start(ap, fmt);
648 if (mon) {
649 monitor_vprintf(mon, fmt, ap);
650 } else {
651 fprintf(stderr, "qemu: ");
652 vfprintf(stderr, fmt, ap);
653 exit(1);
654 }
655 va_end(ap);
656}
657
63a01ef8
AL
658#if defined(CONFIG_SLIRP)
659
660/* slirp network adapter */
661
c92ef6a2
JK
662#define SLIRP_CFG_HOSTFWD 1
663#define SLIRP_CFG_LEGACY 2
ad196a9d 664
b8e8af38
JK
665struct slirp_config_str {
666 struct slirp_config_str *next;
ad196a9d
JK
667 int flags;
668 char str[1024];
c92ef6a2 669 int legacy_format;
b8e8af38
JK
670};
671
9f8bd042 672typedef struct SlirpState {
72cf2d4f 673 QTAILQ_ENTRY(SlirpState) entry;
9f8bd042
JK
674 VLANClientState *vc;
675 Slirp *slirp;
28432466
JK
676#ifndef _WIN32
677 char smb_dir[128];
678#endif
9f8bd042
JK
679} SlirpState;
680
ad196a9d
JK
681static struct slirp_config_str *slirp_configs;
682const char *legacy_tftp_prefix;
683const char *legacy_bootp_filename;
72cf2d4f
BS
684static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks =
685 QTAILQ_HEAD_INITIALIZER(slirp_stacks);
63a01ef8 686
9f8bd042 687static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
3c6a0580 688 int legacy_format);
9f8bd042 689static void slirp_guestfwd(SlirpState *s, Monitor *mon, const char *config_str,
c92ef6a2 690 int legacy_format);
ad196a9d 691
c5b76b38 692#ifndef _WIN32
ad196a9d
JK
693static const char *legacy_smb_export;
694
492efabd 695static void slirp_smb(SlirpState *s, Monitor *mon, const char *exported_dir,
9f8bd042 696 struct in_addr vserver_addr);
28432466
JK
697static void slirp_smb_cleanup(SlirpState *s);
698#else
699static inline void slirp_smb_cleanup(SlirpState *s) { }
c5b76b38 700#endif
b8e8af38 701
9f8bd042 702int slirp_can_output(void *opaque)
63a01ef8 703{
9f8bd042
JK
704 SlirpState *s = opaque;
705
706 return qemu_can_send_packet(s->vc);
63a01ef8
AL
707}
708
9f8bd042 709void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
63a01ef8 710{
9f8bd042
JK
711 SlirpState *s = opaque;
712
63a01ef8
AL
713#ifdef DEBUG_SLIRP
714 printf("slirp output:\n");
715 hex_dump(stdout, pkt, pkt_len);
716#endif
9f8bd042 717 qemu_send_packet(s->vc, pkt, pkt_len);
63a01ef8
AL
718}
719
4f1c942b 720static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
63a01ef8 721{
9f8bd042
JK
722 SlirpState *s = vc->opaque;
723
63a01ef8
AL
724#ifdef DEBUG_SLIRP
725 printf("slirp input:\n");
726 hex_dump(stdout, buf, size);
727#endif
9f8bd042 728 slirp_input(s->slirp, buf, size);
4f1c942b 729 return size;
63a01ef8
AL
730}
731
8d6249a7
AL
732static void net_slirp_cleanup(VLANClientState *vc)
733{
ad0d8c4c
JK
734 SlirpState *s = vc->opaque;
735
736 slirp_cleanup(s->slirp);
28432466 737 slirp_smb_cleanup(s);
72cf2d4f 738 QTAILQ_REMOVE(&slirp_stacks, s, entry);
ad0d8c4c 739 qemu_free(s);
8d6249a7
AL
740}
741
ad196a9d 742static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
c92ef6a2
JK
743 const char *name, int restricted,
744 const char *vnetwork, const char *vhost,
745 const char *vhostname, const char *tftp_export,
746 const char *bootfile, const char *vdhcp_start,
747 const char *vnameserver, const char *smb_export,
748 const char *vsmbserver)
63a01ef8 749{
ad0d8c4c 750 /* default settings according to historic slirp */
8389e7f4
AL
751 struct in_addr net = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
752 struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */
ad0d8c4c
JK
753 struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
754 struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
755 struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
c92ef6a2 756#ifndef _WIN32
ad0d8c4c 757 struct in_addr smbsrv = { .s_addr = 0 };
c92ef6a2 758#endif
ad0d8c4c
JK
759 SlirpState *s;
760 char buf[20];
761 uint32_t addr;
762 int shift;
763 char *end;
3a179c66 764 struct slirp_config_str *config;
ad0d8c4c
JK
765
766 if (!tftp_export) {
767 tftp_export = legacy_tftp_prefix;
768 }
769 if (!bootfile) {
770 bootfile = legacy_bootp_filename;
771 }
c92ef6a2 772
ad0d8c4c
JK
773 if (vnetwork) {
774 if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) {
775 if (!inet_aton(vnetwork, &net)) {
776 return -1;
777 }
778 addr = ntohl(net.s_addr);
779 if (!(addr & 0x80000000)) {
780 mask.s_addr = htonl(0xff000000); /* class A */
781 } else if ((addr & 0xfff00000) == 0xac100000) {
782 mask.s_addr = htonl(0xfff00000); /* priv. 172.16.0.0/12 */
783 } else if ((addr & 0xc0000000) == 0x80000000) {
784 mask.s_addr = htonl(0xffff0000); /* class B */
785 } else if ((addr & 0xffff0000) == 0xc0a80000) {
786 mask.s_addr = htonl(0xffff0000); /* priv. 192.168.0.0/16 */
787 } else if ((addr & 0xffff0000) == 0xc6120000) {
788 mask.s_addr = htonl(0xfffe0000); /* tests 198.18.0.0/15 */
789 } else if ((addr & 0xe0000000) == 0xe0000000) {
790 mask.s_addr = htonl(0xffffff00); /* class C */
c92ef6a2 791 } else {
ad0d8c4c
JK
792 mask.s_addr = htonl(0xfffffff0); /* multicast/reserved */
793 }
794 } else {
795 if (!inet_aton(buf, &net)) {
796 return -1;
797 }
798 shift = strtol(vnetwork, &end, 10);
799 if (*end != '\0') {
800 if (!inet_aton(vnetwork, &mask)) {
c92ef6a2 801 return -1;
c92ef6a2 802 }
ad0d8c4c
JK
803 } else if (shift < 4 || shift > 32) {
804 return -1;
805 } else {
806 mask.s_addr = htonl(0xffffffff << (32 - shift));
c92ef6a2 807 }
c92ef6a2 808 }
ad0d8c4c
JK
809 net.s_addr &= mask.s_addr;
810 host.s_addr = net.s_addr | (htonl(0x0202) & ~mask.s_addr);
811 dhcp.s_addr = net.s_addr | (htonl(0x020f) & ~mask.s_addr);
812 dns.s_addr = net.s_addr | (htonl(0x0203) & ~mask.s_addr);
813 }
c92ef6a2 814
ad0d8c4c
JK
815 if (vhost && !inet_aton(vhost, &host)) {
816 return -1;
817 }
818 if ((host.s_addr & mask.s_addr) != net.s_addr) {
819 return -1;
820 }
c92ef6a2 821
ad0d8c4c
JK
822 if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) {
823 return -1;
824 }
825 if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
826 dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
827 return -1;
828 }
c92ef6a2 829
ad0d8c4c
JK
830 if (vnameserver && !inet_aton(vnameserver, &dns)) {
831 return -1;
832 }
833 if ((dns.s_addr & mask.s_addr) != net.s_addr ||
834 dns.s_addr == host.s_addr) {
835 return -1;
836 }
c92ef6a2
JK
837
838#ifndef _WIN32
ad0d8c4c
JK
839 if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
840 return -1;
841 }
c92ef6a2
JK
842#endif
843
ad0d8c4c
JK
844 s = qemu_mallocz(sizeof(SlirpState));
845 s->slirp = slirp_init(restricted, net, mask, host, vhostname,
846 tftp_export, bootfile, dhcp, dns, s);
72cf2d4f 847 QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
b8e8af38 848
3a179c66 849 for (config = slirp_configs; config; config = config->next) {
ad0d8c4c
JK
850 if (config->flags & SLIRP_CFG_HOSTFWD) {
851 slirp_hostfwd(s, mon, config->str,
852 config->flags & SLIRP_CFG_LEGACY);
853 } else {
854 slirp_guestfwd(s, mon, config->str,
855 config->flags & SLIRP_CFG_LEGACY);
b8e8af38 856 }
ad0d8c4c 857 }
b8e8af38 858#ifndef _WIN32
ad0d8c4c
JK
859 if (!smb_export) {
860 smb_export = legacy_smb_export;
861 }
862 if (smb_export) {
492efabd 863 slirp_smb(s, mon, smb_export, smbsrv);
63a01ef8 864 }
ad0d8c4c 865#endif
b8e8af38 866
9f8bd042
JK
867 s->vc = qemu_new_vlan_client(vlan, model, name, NULL, slirp_receive, NULL,
868 net_slirp_cleanup, s);
fc57bc57
JK
869 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
870 "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');
63a01ef8
AL
871 return 0;
872}
873
f13b572c
JK
874static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
875 const char *stack)
876{
877 VLANClientState *vc;
878
879 if (vlan) {
880 vc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
881 if (!vc) {
882 return NULL;
883 }
884 if (strcmp(vc->model, "user")) {
885 monitor_printf(mon, "invalid device specified\n");
886 return NULL;
887 }
888 return vc->opaque;
889 } else {
72cf2d4f 890 if (QTAILQ_EMPTY(&slirp_stacks)) {
f13b572c
JK
891 monitor_printf(mon, "user mode network stack not in use\n");
892 return NULL;
893 }
72cf2d4f 894 return QTAILQ_FIRST(&slirp_stacks);
f13b572c
JK
895 }
896}
897
1d4daa91 898void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict)
c1261d8d 899{
3c6a0580 900 struct in_addr host_addr = { .s_addr = INADDR_ANY };
c1261d8d
AG
901 int host_port;
902 char buf[256] = "";
f13b572c
JK
903 const char *src_str, *p;
904 SlirpState *s;
c1261d8d 905 int is_udp = 0;
9c12a6f2 906 int err;
1d4daa91
LC
907 const char *arg1 = qdict_get_str(qdict, "arg1");
908 const char *arg2 = qdict_get_try_str(qdict, "arg2");
909 const char *arg3 = qdict_get_try_str(qdict, "arg3");
c1261d8d 910
f13b572c
JK
911 if (arg2) {
912 s = slirp_lookup(mon, arg1, arg2);
913 src_str = arg3;
914 } else {
915 s = slirp_lookup(mon, NULL, NULL);
916 src_str = arg1;
917 }
918 if (!s) {
c1261d8d 919 return;
f3546deb 920 }
c1261d8d 921
3c6a0580 922 if (!src_str || !src_str[0])
c1261d8d
AG
923 goto fail_syntax;
924
f13b572c 925 p = src_str;
c1261d8d
AG
926 get_str_sep(buf, sizeof(buf), &p, ':');
927
928 if (!strcmp(buf, "tcp") || buf[0] == '\0') {
929 is_udp = 0;
930 } else if (!strcmp(buf, "udp")) {
931 is_udp = 1;
932 } else {
933 goto fail_syntax;
934 }
935
3c6a0580
JK
936 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
937 goto fail_syntax;
938 }
939 if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
940 goto fail_syntax;
941 }
942
c1261d8d
AG
943 host_port = atoi(p);
944
72cf2d4f 945 err = slirp_remove_hostfwd(QTAILQ_FIRST(&slirp_stacks)->slirp, is_udp,
9f8bd042 946 host_addr, host_port);
c1261d8d 947
9c12a6f2
JK
948 monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
949 err ? "removed" : "not found");
c1261d8d
AG
950 return;
951
952 fail_syntax:
953 monitor_printf(mon, "invalid format\n");
954}
955
9f8bd042 956static void slirp_hostfwd(SlirpState *s, Monitor *mon, const char *redir_str,
3c6a0580 957 int legacy_format)
63a01ef8 958{
3c6a0580 959 struct in_addr host_addr = { .s_addr = INADDR_ANY };
c92ef6a2 960 struct in_addr guest_addr = { .s_addr = 0 };
63a01ef8 961 int host_port, guest_port;
b8e8af38 962 const char *p;
c92ef6a2 963 char buf[256];
b8e8af38 964 int is_udp;
c92ef6a2 965 char *end;
1c6ed9f3 966
63a01ef8 967 p = redir_str;
f13b572c 968 if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
d4ebe193 969 goto fail_syntax;
b8e8af38 970 }
d4ebe193 971 if (!strcmp(buf, "tcp") || buf[0] == '\0') {
63a01ef8
AL
972 is_udp = 0;
973 } else if (!strcmp(buf, "udp")) {
974 is_udp = 1;
975 } else {
d4ebe193 976 goto fail_syntax;
63a01ef8
AL
977 }
978
3c6a0580
JK
979 if (!legacy_format) {
980 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
981 goto fail_syntax;
982 }
983 if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {
984 goto fail_syntax;
985 }
986 }
987
988 if (get_str_sep(buf, sizeof(buf), &p, legacy_format ? ':' : '-') < 0) {
d4ebe193 989 goto fail_syntax;
b8e8af38 990 }
c92ef6a2
JK
991 host_port = strtol(buf, &end, 0);
992 if (*end != '\0' || host_port < 1 || host_port > 65535) {
d4ebe193 993 goto fail_syntax;
b8e8af38 994 }
63a01ef8 995
b8e8af38 996 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
d4ebe193 997 goto fail_syntax;
b8e8af38 998 }
c92ef6a2 999 if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
d4ebe193 1000 goto fail_syntax;
b8e8af38 1001 }
63a01ef8 1002
c92ef6a2
JK
1003 guest_port = strtol(p, &end, 0);
1004 if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
d4ebe193 1005 goto fail_syntax;
b8e8af38 1006 }
63a01ef8 1007
9f8bd042
JK
1008 if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
1009 guest_port) < 0) {
c92ef6a2
JK
1010 config_error(mon, "could not set up host forwarding rule '%s'\n",
1011 redir_str);
63a01ef8
AL
1012 }
1013 return;
d4ebe193
AL
1014
1015 fail_syntax:
c92ef6a2 1016 config_error(mon, "invalid host forwarding rule '%s'\n", redir_str);
63a01ef8
AL
1017}
1018
1d4daa91 1019void net_slirp_hostfwd_add(Monitor *mon, const QDict *qdict)
b8e8af38 1020{
f13b572c
JK
1021 const char *redir_str;
1022 SlirpState *s;
1d4daa91
LC
1023 const char *arg1 = qdict_get_str(qdict, "arg1");
1024 const char *arg2 = qdict_get_try_str(qdict, "arg2");
1025 const char *arg3 = qdict_get_try_str(qdict, "arg3");
f13b572c
JK
1026
1027 if (arg2) {
1028 s = slirp_lookup(mon, arg1, arg2);
1029 redir_str = arg3;
1030 } else {
1031 s = slirp_lookup(mon, NULL, NULL);
1032 redir_str = arg1;
1033 }
1034 if (s) {
1035 slirp_hostfwd(s, mon, redir_str, 0);
b8e8af38
JK
1036 }
1037
f3546deb
JK
1038}
1039
1040void net_slirp_redir(const char *redir_str)
1041{
1042 struct slirp_config_str *config;
1043
72cf2d4f 1044 if (QTAILQ_EMPTY(&slirp_stacks)) {
f3546deb
JK
1045 config = qemu_malloc(sizeof(*config));
1046 pstrcpy(config->str, sizeof(config->str), redir_str);
3c6a0580 1047 config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY;
f3546deb
JK
1048 config->next = slirp_configs;
1049 slirp_configs = config;
b8e8af38
JK
1050 return;
1051 }
1052
72cf2d4f 1053 slirp_hostfwd(QTAILQ_FIRST(&slirp_stacks), NULL, redir_str, 1);
b8e8af38
JK
1054}
1055
63a01ef8
AL
1056#ifndef _WIN32
1057
63a01ef8 1058/* automatic user mode samba server configuration */
28432466 1059static void slirp_smb_cleanup(SlirpState *s)
63a01ef8 1060{
28432466 1061 char cmd[128];
09c18925 1062
28432466
JK
1063 if (s->smb_dir[0] != '\0') {
1064 snprintf(cmd, sizeof(cmd), "rm -rf %s", s->smb_dir);
1065 system(cmd);
1066 s->smb_dir[0] = '\0';
1067 }
63a01ef8
AL
1068}
1069
492efabd 1070static void slirp_smb(SlirpState* s, Monitor *mon, const char *exported_dir,
9f8bd042 1071 struct in_addr vserver_addr)
63a01ef8 1072{
28432466
JK
1073 static int instance;
1074 char smb_conf[128];
1075 char smb_cmdline[128];
63a01ef8
AL
1076 FILE *f;
1077
28432466
JK
1078 snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d",
1079 (long)getpid(), instance++);
1080 if (mkdir(s->smb_dir, 0700) < 0) {
1081 config_error(mon, "could not create samba server dir '%s'\n",
1082 s->smb_dir);
492efabd 1083 return;
63a01ef8 1084 }
28432466 1085 snprintf(smb_conf, sizeof(smb_conf), "%s/%s", s->smb_dir, "smb.conf");
63a01ef8
AL
1086
1087 f = fopen(smb_conf, "w");
1088 if (!f) {
28432466 1089 slirp_smb_cleanup(s);
492efabd
JK
1090 config_error(mon, "could not create samba server "
1091 "configuration file '%s'\n", smb_conf);
1092 return;
63a01ef8
AL
1093 }
1094 fprintf(f,
1095 "[global]\n"
1096 "private dir=%s\n"
1097 "smb ports=0\n"
1098 "socket address=127.0.0.1\n"
1099 "pid directory=%s\n"
1100 "lock directory=%s\n"
1101 "log file=%s/log.smbd\n"
1102 "smb passwd file=%s/smbpasswd\n"
1103 "security = share\n"
1104 "[qemu]\n"
1105 "path=%s\n"
1106 "read only=no\n"
1107 "guest ok=yes\n",
28432466
JK
1108 s->smb_dir,
1109 s->smb_dir,
1110 s->smb_dir,
1111 s->smb_dir,
1112 s->smb_dir,
63a01ef8
AL
1113 exported_dir
1114 );
1115 fclose(f);
63a01ef8
AL
1116
1117 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
1118 SMBD_COMMAND, smb_conf);
1119
bb53fc53 1120 if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
28432466 1121 slirp_smb_cleanup(s);
492efabd 1122 config_error(mon, "conflicting/invalid smbserver address\n");
c92ef6a2 1123 }
63a01ef8
AL
1124}
1125
ad196a9d 1126/* automatic user mode samba server configuration (legacy interface) */
b8e8af38
JK
1127void net_slirp_smb(const char *exported_dir)
1128{
c92ef6a2
JK
1129 struct in_addr vserver_addr = { .s_addr = 0 };
1130
ad196a9d 1131 if (legacy_smb_export) {
b8e8af38
JK
1132 fprintf(stderr, "-smb given twice\n");
1133 exit(1);
1134 }
ad196a9d 1135 legacy_smb_export = exported_dir;
72cf2d4f
BS
1136 if (!QTAILQ_EMPTY(&slirp_stacks)) {
1137 slirp_smb(QTAILQ_FIRST(&slirp_stacks), NULL, exported_dir,
492efabd 1138 vserver_addr);
b8e8af38
JK
1139 }
1140}
1141
63a01ef8 1142#endif /* !defined(_WIN32) */
b8e8af38 1143
c92ef6a2 1144struct GuestFwd {
8ca9217d 1145 CharDriverState *hd;
c92ef6a2 1146 struct in_addr server;
8ca9217d 1147 int port;
9f8bd042 1148 Slirp *slirp;
511d2b14 1149};
8ca9217d 1150
c92ef6a2 1151static int guestfwd_can_read(void *opaque)
8ca9217d 1152{
c92ef6a2 1153 struct GuestFwd *fwd = opaque;
9f8bd042 1154 return slirp_socket_can_recv(fwd->slirp, fwd->server, fwd->port);
8ca9217d
AL
1155}
1156
c92ef6a2 1157static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
8ca9217d 1158{
c92ef6a2 1159 struct GuestFwd *fwd = opaque;
9f8bd042 1160 slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
8ca9217d
AL
1161}
1162
9f8bd042 1163static void slirp_guestfwd(SlirpState *s, Monitor *mon, const char *config_str,
c92ef6a2 1164 int legacy_format)
ad196a9d 1165{
c92ef6a2
JK
1166 struct in_addr server = { .s_addr = 0 };
1167 struct GuestFwd *fwd;
1168 const char *p;
1169 char buf[128];
1170 char *end;
ad196a9d
JK
1171 int port;
1172
c92ef6a2
JK
1173 p = config_str;
1174 if (legacy_format) {
1175 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
1176 goto fail_syntax;
1177 }
1178 } else {
1179 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
1180 goto fail_syntax;
1181 }
1182 if (strcmp(buf, "tcp") && buf[0] != '\0') {
1183 goto fail_syntax;
1184 }
1185 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
1186 goto fail_syntax;
1187 }
1188 if (buf[0] != '\0' && !inet_aton(buf, &server)) {
1189 goto fail_syntax;
1190 }
1191 if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) {
1192 goto fail_syntax;
1193 }
1194 }
1195 port = strtol(buf, &end, 10);
1196 if (*end != '\0' || port < 1 || port > 65535) {
1197 goto fail_syntax;
ad196a9d 1198 }
ad196a9d 1199
c92ef6a2
JK
1200 fwd = qemu_malloc(sizeof(struct GuestFwd));
1201 snprintf(buf, sizeof(buf), "guestfwd.tcp:%d", port);
1202 fwd->hd = qemu_chr_open(buf, p, NULL);
1203 if (!fwd->hd) {
1204 config_error(mon, "could not open guest forwarding device '%s'\n",
1205 buf);
1206 qemu_free(fwd);
ad196a9d
JK
1207 return;
1208 }
ad196a9d 1209
bb53fc53 1210 if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
c92ef6a2
JK
1211 config_error(mon, "conflicting/invalid host:port in guest forwarding "
1212 "rule '%s'\n", config_str);
1213 qemu_free(fwd);
1214 return;
1215 }
bb53fc53
JK
1216 fwd->server = server;
1217 fwd->port = port;
1218 fwd->slirp = s->slirp;
1219
c92ef6a2
JK
1220 qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
1221 NULL, fwd);
ad196a9d 1222 return;
c92ef6a2
JK
1223
1224 fail_syntax:
1225 config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
ad196a9d
JK
1226}
1227
6dbe553f
JK
1228void do_info_usernet(Monitor *mon)
1229{
b1c99fcd 1230 SlirpState *s;
9f8bd042 1231
72cf2d4f 1232 QTAILQ_FOREACH(s, &slirp_stacks, entry) {
b1c99fcd
JK
1233 monitor_printf(mon, "VLAN %d (%s):\n", s->vc->vlan->id, s->vc->name);
1234 slirp_connection_info(s->slirp, mon);
9f8bd042 1235 }
6dbe553f
JK
1236}
1237
63a01ef8
AL
1238#endif /* CONFIG_SLIRP */
1239
1240#if !defined(_WIN32)
1241
1242typedef struct TAPState {
1243 VLANClientState *vc;
1244 int fd;
1245 char down_script[1024];
973cbd37 1246 char down_script_arg[128];
5b01e886 1247 uint8_t buf[4096];
b664e367 1248 unsigned int read_poll : 1;
1f7babf6 1249 unsigned int write_poll : 1;
63a01ef8
AL
1250} TAPState;
1251
b946a153
AL
1252static int launch_script(const char *setup_script, const char *ifname, int fd);
1253
b664e367
MM
1254static int tap_can_send(void *opaque);
1255static void tap_send(void *opaque);
1f7babf6 1256static void tap_writable(void *opaque);
b664e367
MM
1257
1258static void tap_update_fd_handler(TAPState *s)
1259{
1260 qemu_set_fd_handler2(s->fd,
1261 s->read_poll ? tap_can_send : NULL,
1262 s->read_poll ? tap_send : NULL,
1f7babf6 1263 s->write_poll ? tap_writable : NULL,
b664e367
MM
1264 s);
1265}
1266
1267static void tap_read_poll(TAPState *s, int enable)
1268{
1269 s->read_poll = !!enable;
1270 tap_update_fd_handler(s);
1271}
1272
1f7babf6
MM
1273static void tap_write_poll(TAPState *s, int enable)
1274{
1275 s->write_poll = !!enable;
1276 tap_update_fd_handler(s);
1277}
1278
1279static void tap_writable(void *opaque)
1280{
1281 TAPState *s = opaque;
1282
1283 tap_write_poll(s, 0);
1284
1285 qemu_flush_queued_packets(s->vc);
1286}
1287
e3f5ec2b 1288static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
b535b7b2
AL
1289 int iovcnt)
1290{
e3f5ec2b 1291 TAPState *s = vc->opaque;
b535b7b2
AL
1292 ssize_t len;
1293
1294 do {
1295 len = writev(s->fd, iov, iovcnt);
1f7babf6
MM
1296 } while (len == -1 && errno == EINTR);
1297
1298 if (len == -1 && errno == EAGAIN) {
1299 tap_write_poll(s, 1);
1300 return 0;
1301 }
b535b7b2
AL
1302
1303 return len;
1304}
b535b7b2 1305
4f1c942b 1306static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
63a01ef8 1307{
e3f5ec2b 1308 TAPState *s = vc->opaque;
4f1c942b
MM
1309 ssize_t len;
1310
1311 do {
1312 len = write(s->fd, buf, size);
1313 } while (len == -1 && (errno == EINTR || errno == EAGAIN));
1314
1315 return len;
63a01ef8
AL
1316}
1317
3471b757
MM
1318static int tap_can_send(void *opaque)
1319{
1320 TAPState *s = opaque;
1321
1322 return qemu_can_send_packet(s->vc);
1323}
1324
63a01ef8 1325#ifdef __sun__
5a6d8815
MM
1326static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
1327{
63a01ef8
AL
1328 struct strbuf sbuf;
1329 int f = 0;
5a6d8815
MM
1330
1331 sbuf.maxlen = maxlen;
3f4cb3d3 1332 sbuf.buf = (char *)buf;
5a6d8815
MM
1333
1334 return getmsg(tapfd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
1335}
63a01ef8 1336#else
5a6d8815
MM
1337static ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
1338{
1339 return read(tapfd, buf, maxlen);
1340}
63a01ef8 1341#endif
5a6d8815 1342
783527a9 1343static void tap_send_completed(VLANClientState *vc, ssize_t len)
e19eb224
MM
1344{
1345 TAPState *s = vc->opaque;
b664e367 1346 tap_read_poll(s, 1);
e19eb224
MM
1347}
1348
5a6d8815
MM
1349static void tap_send(void *opaque)
1350{
1351 TAPState *s = opaque;
5a6d8815
MM
1352 int size;
1353
e19eb224
MM
1354 do {
1355 size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
1356 if (size <= 0) {
1357 break;
1358 }
1359
1360 size = qemu_send_packet_async(s->vc, s->buf, size, tap_send_completed);
1361 if (size == 0) {
b664e367 1362 tap_read_poll(s, 0);
e19eb224
MM
1363 }
1364 } while (size > 0);
63a01ef8
AL
1365}
1366
0df0ff6d 1367#ifdef TUNSETSNDBUF
fc5b81d1
MM
1368/* sndbuf should be set to a value lower than the tx queue
1369 * capacity of any destination network interface.
1370 * Ethernet NICs generally have txqueuelen=1000, so 1Mb is
1371 * a good default, given a 1500 byte MTU.
1372 */
1373#define TAP_DEFAULT_SNDBUF 1024*1024
1374
1375static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
1376{
1377 int sndbuf = TAP_DEFAULT_SNDBUF;
1378
1379 if (sndbuf_str) {
1380 sndbuf = atoi(sndbuf_str);
1381 }
1382
1383 if (!sndbuf) {
1384 sndbuf = INT_MAX;
1385 }
1386
d026fb6d 1387 if (ioctl(s->fd, TUNSETSNDBUF, &sndbuf) == -1 && sndbuf_str) {
0df0ff6d
MM
1388 config_error(mon, "TUNSETSNDBUF ioctl failed: %s\n",
1389 strerror(errno));
1390 }
fc5b81d1 1391}
0df0ff6d 1392#else
fc5b81d1
MM
1393static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)
1394{
1395 if (sndbuf_str) {
1396 config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");
1397 }
0df0ff6d 1398}
fc5b81d1 1399#endif /* TUNSETSNDBUF */
0df0ff6d 1400
b946a153
AL
1401static void tap_cleanup(VLANClientState *vc)
1402{
1403 TAPState *s = vc->opaque;
1404
b9adce2c
MM
1405 qemu_purge_queued_packets(vc);
1406
b946a153
AL
1407 if (s->down_script[0])
1408 launch_script(s->down_script, s->down_script_arg, s->fd);
1409
b664e367 1410 tap_read_poll(s, 0);
1f7babf6 1411 tap_write_poll(s, 0);
b946a153
AL
1412 close(s->fd);
1413 qemu_free(s);
1414}
1415
63a01ef8
AL
1416/* fd support */
1417
7a9f6e4a
AL
1418static TAPState *net_tap_fd_init(VLANState *vlan,
1419 const char *model,
1420 const char *name,
1421 int fd)
63a01ef8
AL
1422{
1423 TAPState *s;
1424
1425 s = qemu_mallocz(sizeof(TAPState));
63a01ef8 1426 s->fd = fd;
463af534
MM
1427 s->vc = qemu_new_vlan_client(vlan, model, name, NULL, tap_receive,
1428 tap_receive_iov, tap_cleanup, s);
b664e367 1429 tap_read_poll(s, 1);
7cb7434b 1430 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
63a01ef8
AL
1431 return s;
1432}
1433
71e72a19 1434#if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
63a01ef8
AL
1435static int tap_open(char *ifname, int ifname_size)
1436{
1437 int fd;
1438 char *dev;
1439 struct stat s;
1440
1441 TFR(fd = open("/dev/tap", O_RDWR));
1442 if (fd < 0) {
1443 fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
1444 return -1;
1445 }
1446
1447 fstat(fd, &s);
1448 dev = devname(s.st_rdev, S_IFCHR);
1449 pstrcpy(ifname, ifname_size, dev);
1450
1451 fcntl(fd, F_SETFL, O_NONBLOCK);
1452 return fd;
1453}
1454#elif defined(__sun__)
1455#define TUNNEWPPA (('T'<<16) | 0x0001)
1456/*
1457 * Allocate TAP device, returns opened fd.
1458 * Stores dev name in the first arg(must be large enough).
1459 */
3f4cb3d3 1460static int tap_alloc(char *dev, size_t dev_size)
63a01ef8
AL
1461{
1462 int tap_fd, if_fd, ppa = -1;
1463 static int ip_fd = 0;
1464 char *ptr;
1465
1466 static int arp_fd = 0;
1467 int ip_muxid, arp_muxid;
1468 struct strioctl strioc_if, strioc_ppa;
1469 int link_type = I_PLINK;;
1470 struct lifreq ifr;
1471 char actual_name[32] = "";
1472
1473 memset(&ifr, 0x0, sizeof(ifr));
1474
1475 if( *dev ){
1476 ptr = dev;
47398b9c 1477 while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++;
63a01ef8
AL
1478 ppa = atoi(ptr);
1479 }
1480
1481 /* Check if IP device was opened */
1482 if( ip_fd )
1483 close(ip_fd);
1484
1485 TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
1486 if (ip_fd < 0) {
1487 syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
1488 return -1;
1489 }
1490
1491 TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
1492 if (tap_fd < 0) {
1493 syslog(LOG_ERR, "Can't open /dev/tap");
1494 return -1;
1495 }
1496
1497 /* Assign a new PPA and get its unit number. */
1498 strioc_ppa.ic_cmd = TUNNEWPPA;
1499 strioc_ppa.ic_timout = 0;
1500 strioc_ppa.ic_len = sizeof(ppa);
1501 strioc_ppa.ic_dp = (char *)&ppa;
1502 if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
1503 syslog (LOG_ERR, "Can't assign new interface");
1504
1505 TFR(if_fd = open("/dev/tap", O_RDWR, 0));
1506 if (if_fd < 0) {
1507 syslog(LOG_ERR, "Can't open /dev/tap (2)");
1508 return -1;
1509 }
1510 if(ioctl(if_fd, I_PUSH, "ip") < 0){
1511 syslog(LOG_ERR, "Can't push IP module");
1512 return -1;
1513 }
1514
1515 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
1516 syslog(LOG_ERR, "Can't get flags\n");
1517
1518 snprintf (actual_name, 32, "tap%d", ppa);
1519 pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
1520
1521 ifr.lifr_ppa = ppa;
1522 /* Assign ppa according to the unit number returned by tun device */
1523
1524 if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
1525 syslog (LOG_ERR, "Can't set PPA %d", ppa);
1526 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
1527 syslog (LOG_ERR, "Can't get flags\n");
1528 /* Push arp module to if_fd */
1529 if (ioctl (if_fd, I_PUSH, "arp") < 0)
1530 syslog (LOG_ERR, "Can't push ARP module (2)");
1531
1532 /* Push arp module to ip_fd */
1533 if (ioctl (ip_fd, I_POP, NULL) < 0)
1534 syslog (LOG_ERR, "I_POP failed\n");
1535 if (ioctl (ip_fd, I_PUSH, "arp") < 0)
1536 syslog (LOG_ERR, "Can't push ARP module (3)\n");
1537 /* Open arp_fd */
1538 TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
1539 if (arp_fd < 0)
1540 syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
1541
1542 /* Set ifname to arp */
1543 strioc_if.ic_cmd = SIOCSLIFNAME;
1544 strioc_if.ic_timout = 0;
1545 strioc_if.ic_len = sizeof(ifr);
1546 strioc_if.ic_dp = (char *)&ifr;
1547 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
1548 syslog (LOG_ERR, "Can't set ifname to arp\n");
1549 }
1550
1551 if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
1552 syslog(LOG_ERR, "Can't link TAP device to IP");
1553 return -1;
1554 }
1555
1556 if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
1557 syslog (LOG_ERR, "Can't link TAP device to ARP");
1558
1559 close (if_fd);
1560
1561 memset(&ifr, 0x0, sizeof(ifr));
1562 pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name);
1563 ifr.lifr_ip_muxid = ip_muxid;
1564 ifr.lifr_arp_muxid = arp_muxid;
1565
1566 if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
1567 {
1568 ioctl (ip_fd, I_PUNLINK , arp_muxid);
1569 ioctl (ip_fd, I_PUNLINK, ip_muxid);
1570 syslog (LOG_ERR, "Can't set multiplexor id");
1571 }
1572
1573 snprintf(dev, dev_size, "tap%d", ppa);
1574 return tap_fd;
1575}
1576
1577static int tap_open(char *ifname, int ifname_size)
1578{
1579 char dev[10]="";
1580 int fd;
1581 if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
1582 fprintf(stderr, "Cannot allocate TAP device\n");
1583 return -1;
1584 }
1585 pstrcpy(ifname, ifname_size, dev);
1586 fcntl(fd, F_SETFL, O_NONBLOCK);
1587 return fd;
1588}
b29fe3ed 1589#elif defined (_AIX)
1590static int tap_open(char *ifname, int ifname_size)
1591{
1592 fprintf (stderr, "no tap on AIX\n");
1593 return -1;
1594}
63a01ef8
AL
1595#else
1596static int tap_open(char *ifname, int ifname_size)
1597{
1598 struct ifreq ifr;
1599 int fd, ret;
1600
1601 TFR(fd = open("/dev/net/tun", O_RDWR));
1602 if (fd < 0) {
1603 fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
1604 return -1;
1605 }
1606 memset(&ifr, 0, sizeof(ifr));
1607 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1608 if (ifname[0] != '\0')
1609 pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
1610 else
1611 pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
1612 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
1613 if (ret != 0) {
1614 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
1615 close(fd);
1616 return -1;
1617 }
1618 pstrcpy(ifname, ifname_size, ifr.ifr_name);
1619 fcntl(fd, F_SETFL, O_NONBLOCK);
1620 return fd;
1621}
1622#endif
1623
1624static int launch_script(const char *setup_script, const char *ifname, int fd)
1625{
7c3370d4 1626 sigset_t oldmask, mask;
63a01ef8
AL
1627 int pid, status;
1628 char *args[3];
1629 char **parg;
1630
7c3370d4
JK
1631 sigemptyset(&mask);
1632 sigaddset(&mask, SIGCHLD);
1633 sigprocmask(SIG_BLOCK, &mask, &oldmask);
1634
1635 /* try to launch network script */
1636 pid = fork();
1637 if (pid == 0) {
1638 int open_max = sysconf(_SC_OPEN_MAX), i;
1639
1640 for (i = 0; i < open_max; i++) {
1641 if (i != STDIN_FILENO &&
1642 i != STDOUT_FILENO &&
1643 i != STDERR_FILENO &&
1644 i != fd) {
1645 close(i);
63a01ef8
AL
1646 }
1647 }
7c3370d4
JK
1648 parg = args;
1649 *parg++ = (char *)setup_script;
1650 *parg++ = (char *)ifname;
1651 *parg++ = NULL;
1652 execv(setup_script, args);
1653 _exit(1);
1654 } else if (pid > 0) {
1655 while (waitpid(pid, &status, 0) != pid) {
1656 /* loop */
1657 }
1658 sigprocmask(SIG_SETMASK, &oldmask, NULL);
1659
1660 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
1661 return 0;
1662 }
1663 }
1664 fprintf(stderr, "%s: could not launch network script\n", setup_script);
1665 return -1;
63a01ef8
AL
1666}
1667
4a77b25e
MM
1668static TAPState *net_tap_init(VLANState *vlan, const char *model,
1669 const char *name, const char *ifname1,
1670 const char *setup_script, const char *down_script)
63a01ef8
AL
1671{
1672 TAPState *s;
1673 int fd;
1674 char ifname[128];
1675
1676 if (ifname1 != NULL)
1677 pstrcpy(ifname, sizeof(ifname), ifname1);
1678 else
1679 ifname[0] = '\0';
1680 TFR(fd = tap_open(ifname, sizeof(ifname)));
1681 if (fd < 0)
4a77b25e 1682 return NULL;
63a01ef8
AL
1683
1684 if (!setup_script || !strcmp(setup_script, "no"))
1685 setup_script = "";
4a77b25e
MM
1686 if (setup_script[0] != '\0' &&
1687 launch_script(setup_script, ifname, fd)) {
1688 return NULL;
63a01ef8 1689 }
7a9f6e4a 1690 s = net_tap_fd_init(vlan, model, name, fd);
63a01ef8 1691 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
7cb7434b
AL
1692 "ifname=%s,script=%s,downscript=%s",
1693 ifname, setup_script, down_script);
973cbd37 1694 if (down_script && strcmp(down_script, "no")) {
63a01ef8 1695 snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
973cbd37
AL
1696 snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);
1697 }
4a77b25e 1698 return s;
63a01ef8
AL
1699}
1700
1701#endif /* !_WIN32 */
1702
1703#if defined(CONFIG_VDE)
1704typedef struct VDEState {
1705 VLANClientState *vc;
1706 VDECONN *vde;
1707} VDEState;
1708
1709static void vde_to_qemu(void *opaque)
1710{
1711 VDEState *s = opaque;
1712 uint8_t buf[4096];
1713 int size;
1714
cc63bb0f 1715 size = vde_recv(s->vde, (char *)buf, sizeof(buf), 0);
63a01ef8
AL
1716 if (size > 0) {
1717 qemu_send_packet(s->vc, buf, size);
1718 }
1719}
1720
4f1c942b 1721static ssize_t vde_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
63a01ef8 1722{
e3f5ec2b 1723 VDEState *s = vc->opaque;
068daedd 1724 ssize_t ret;
4f1c942b
MM
1725
1726 do {
1727 ret = vde_send(s->vde, (const char *)buf, size, 0);
1728 } while (ret < 0 && errno == EINTR);
1729
1730 return ret;
63a01ef8
AL
1731}
1732
b946a153
AL
1733static void vde_cleanup(VLANClientState *vc)
1734{
1735 VDEState *s = vc->opaque;
1736 qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
1737 vde_close(s->vde);
1738 qemu_free(s);
1739}
1740
7a9f6e4a
AL
1741static int net_vde_init(VLANState *vlan, const char *model,
1742 const char *name, const char *sock,
bf38c1a0 1743 int port, const char *group, int mode)
63a01ef8
AL
1744{
1745 VDEState *s;
1746 char *init_group = strlen(group) ? (char *)group : NULL;
1747 char *init_sock = strlen(sock) ? (char *)sock : NULL;
1748
1749 struct vde_open_args args = {
1750 .port = port,
1751 .group = init_group,
1752 .mode = mode,
1753 };
1754
1755 s = qemu_mallocz(sizeof(VDEState));
cc63bb0f 1756 s->vde = vde_open(init_sock, (char *)"QEMU", &args);
63a01ef8
AL
1757 if (!s->vde){
1758 free(s);
1759 return -1;
1760 }
e3f5ec2b 1761 s->vc = qemu_new_vlan_client(vlan, model, name, NULL, vde_receive,
b946a153 1762 NULL, vde_cleanup, s);
63a01ef8 1763 qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
7cb7434b 1764 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
63a01ef8
AL
1765 sock, vde_datafd(s->vde));
1766 return 0;
1767}
1768#endif
1769
1770/* network connection */
1771typedef struct NetSocketState {
1772 VLANClientState *vc;
1773 int fd;
1774 int state; /* 0 = getting length, 1 = getting data */
abcd2baa
AL
1775 unsigned int index;
1776 unsigned int packet_len;
63a01ef8
AL
1777 uint8_t buf[4096];
1778 struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
1779} NetSocketState;
1780
1781typedef struct NetSocketListenState {
1782 VLANState *vlan;
bf38c1a0 1783 char *model;
7a9f6e4a 1784 char *name;
63a01ef8
AL
1785 int fd;
1786} NetSocketListenState;
1787
1788/* XXX: we consider we can send the whole packet without blocking */
4f1c942b 1789static ssize_t net_socket_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
63a01ef8 1790{
e3f5ec2b 1791 NetSocketState *s = vc->opaque;
63a01ef8
AL
1792 uint32_t len;
1793 len = htonl(size);
1794
1795 send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4f1c942b 1796 return send_all(s->fd, buf, size);
63a01ef8
AL
1797}
1798
4f1c942b 1799static ssize_t net_socket_receive_dgram(VLANClientState *vc, const uint8_t *buf, size_t size)
63a01ef8 1800{
e3f5ec2b 1801 NetSocketState *s = vc->opaque;
4f1c942b 1802
70503264 1803 return sendto(s->fd, (const void *)buf, size, 0,
4f1c942b 1804 (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
63a01ef8
AL
1805}
1806
1807static void net_socket_send(void *opaque)
1808{
1809 NetSocketState *s = opaque;
abcd2baa
AL
1810 int size, err;
1811 unsigned l;
63a01ef8
AL
1812 uint8_t buf1[4096];
1813 const uint8_t *buf;
1814
c5b76b38 1815 size = recv(s->fd, (void *)buf1, sizeof(buf1), 0);
63a01ef8
AL
1816 if (size < 0) {
1817 err = socket_error();
1818 if (err != EWOULDBLOCK)
1819 goto eoc;
1820 } else if (size == 0) {
1821 /* end of connection */
1822 eoc:
1823 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1824 closesocket(s->fd);
1825 return;
1826 }
1827 buf = buf1;
1828 while (size > 0) {
1829 /* reassemble a packet from the network */
1830 switch(s->state) {
1831 case 0:
1832 l = 4 - s->index;
1833 if (l > size)
1834 l = size;
1835 memcpy(s->buf + s->index, buf, l);
1836 buf += l;
1837 size -= l;
1838 s->index += l;
1839 if (s->index == 4) {
1840 /* got length */
1841 s->packet_len = ntohl(*(uint32_t *)s->buf);
1842 s->index = 0;
1843 s->state = 1;
1844 }
1845 break;
1846 case 1:
1847 l = s->packet_len - s->index;
1848 if (l > size)
1849 l = size;
abcd2baa
AL
1850 if (s->index + l <= sizeof(s->buf)) {
1851 memcpy(s->buf + s->index, buf, l);
1852 } else {
1853 fprintf(stderr, "serious error: oversized packet received,"
1854 "connection terminated.\n");
1855 s->state = 0;
1856 goto eoc;
1857 }
1858
63a01ef8
AL
1859 s->index += l;
1860 buf += l;
1861 size -= l;
1862 if (s->index >= s->packet_len) {
1863 qemu_send_packet(s->vc, s->buf, s->packet_len);
1864 s->index = 0;
1865 s->state = 0;
1866 }
1867 break;
1868 }
1869 }
1870}
1871
1872static void net_socket_send_dgram(void *opaque)
1873{
1874 NetSocketState *s = opaque;
1875 int size;
1876
c5b76b38 1877 size = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0);
63a01ef8
AL
1878 if (size < 0)
1879 return;
1880 if (size == 0) {
1881 /* end of connection */
1882 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1883 return;
1884 }
1885 qemu_send_packet(s->vc, s->buf, size);
1886}
1887
1888static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
1889{
1890 struct ip_mreq imr;
1891 int fd;
1892 int val, ret;
1893 if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
1894 fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
1895 inet_ntoa(mcastaddr->sin_addr),
1896 (int)ntohl(mcastaddr->sin_addr.s_addr));
1897 return -1;
1898
1899 }
1900 fd = socket(PF_INET, SOCK_DGRAM, 0);
1901 if (fd < 0) {
1902 perror("socket(PF_INET, SOCK_DGRAM)");
1903 return -1;
1904 }
1905
1906 val = 1;
1907 ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1908 (const char *)&val, sizeof(val));
1909 if (ret < 0) {
1910 perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
1911 goto fail;
1912 }
1913
1914 ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
1915 if (ret < 0) {
1916 perror("bind");
1917 goto fail;
1918 }
1919
1920 /* Add host to multicast group */
1921 imr.imr_multiaddr = mcastaddr->sin_addr;
1922 imr.imr_interface.s_addr = htonl(INADDR_ANY);
1923
1924 ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1925 (const char *)&imr, sizeof(struct ip_mreq));
1926 if (ret < 0) {
1927 perror("setsockopt(IP_ADD_MEMBERSHIP)");
1928 goto fail;
1929 }
1930
1931 /* Force mcast msgs to loopback (eg. several QEMUs in same host */
1932 val = 1;
1933 ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
1934 (const char *)&val, sizeof(val));
1935 if (ret < 0) {
1936 perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
1937 goto fail;
1938 }
1939
1940 socket_set_nonblock(fd);
1941 return fd;
1942fail:
1943 if (fd >= 0)
1944 closesocket(fd);
1945 return -1;
1946}
1947
b946a153
AL
1948static void net_socket_cleanup(VLANClientState *vc)
1949{
1950 NetSocketState *s = vc->opaque;
1951 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
1952 close(s->fd);
1953 qemu_free(s);
1954}
1955
7a9f6e4a
AL
1956static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
1957 const char *model,
1958 const char *name,
bf38c1a0 1959 int fd, int is_connected)
63a01ef8
AL
1960{
1961 struct sockaddr_in saddr;
1962 int newfd;
1963 socklen_t saddr_len;
1964 NetSocketState *s;
1965
1966 /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
1967 * Because this may be "shared" socket from a "master" process, datagrams would be recv()
1968 * by ONLY ONE process: we must "clone" this dgram socket --jjo
1969 */
1970
1971 if (is_connected) {
1972 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
1973 /* must be bound */
1974 if (saddr.sin_addr.s_addr==0) {
1975 fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
1976 fd);
1977 return NULL;
1978 }
1979 /* clone dgram socket */
1980 newfd = net_socket_mcast_create(&saddr);
1981 if (newfd < 0) {
1982 /* error already reported by net_socket_mcast_create() */
1983 close(fd);
1984 return NULL;
1985 }
1986 /* clone newfd to fd, close newfd */
1987 dup2(newfd, fd);
1988 close(newfd);
1989
1990 } else {
1991 fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
1992 fd, strerror(errno));
1993 return NULL;
1994 }
1995 }
1996
1997 s = qemu_mallocz(sizeof(NetSocketState));
63a01ef8
AL
1998 s->fd = fd;
1999
463af534 2000 s->vc = qemu_new_vlan_client(vlan, model, name, NULL, net_socket_receive_dgram,
b946a153 2001 NULL, net_socket_cleanup, s);
63a01ef8
AL
2002 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
2003
2004 /* mcast: save bound address as dst */
2005 if (is_connected) s->dgram_dst=saddr;
2006
2007 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2008 "socket: fd=%d (%s mcast=%s:%d)",
2009 fd, is_connected? "cloned" : "",
2010 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2011 return s;
2012}
2013
2014static void net_socket_connect(void *opaque)
2015{
2016 NetSocketState *s = opaque;
2017 qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
2018}
2019
7a9f6e4a
AL
2020static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
2021 const char *model,
2022 const char *name,
bf38c1a0 2023 int fd, int is_connected)
63a01ef8
AL
2024{
2025 NetSocketState *s;
2026 s = qemu_mallocz(sizeof(NetSocketState));
63a01ef8 2027 s->fd = fd;
463af534 2028 s->vc = qemu_new_vlan_client(vlan, model, name, NULL, net_socket_receive,
b946a153 2029 NULL, net_socket_cleanup, s);
63a01ef8
AL
2030 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2031 "socket: fd=%d", fd);
2032 if (is_connected) {
2033 net_socket_connect(s);
2034 } else {
2035 qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
2036 }
2037 return s;
2038}
2039
7a9f6e4a
AL
2040static NetSocketState *net_socket_fd_init(VLANState *vlan,
2041 const char *model, const char *name,
bf38c1a0 2042 int fd, int is_connected)
63a01ef8 2043{
acedcfbf 2044 int so_type = -1, optlen=sizeof(so_type);
63a01ef8
AL
2045
2046 if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
2047 (socklen_t *)&optlen)< 0) {
2048 fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
2049 return NULL;
2050 }
2051 switch(so_type) {
2052 case SOCK_DGRAM:
7a9f6e4a 2053 return net_socket_fd_init_dgram(vlan, model, name, fd, is_connected);
63a01ef8 2054 case SOCK_STREAM:
7a9f6e4a 2055 return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
63a01ef8
AL
2056 default:
2057 /* who knows ... this could be a eg. a pty, do warn and continue as stream */
2058 fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
7a9f6e4a 2059 return net_socket_fd_init_stream(vlan, model, name, fd, is_connected);
63a01ef8
AL
2060 }
2061 return NULL;
2062}
2063
2064static void net_socket_accept(void *opaque)
2065{
2066 NetSocketListenState *s = opaque;
2067 NetSocketState *s1;
2068 struct sockaddr_in saddr;
2069 socklen_t len;
2070 int fd;
2071
2072 for(;;) {
2073 len = sizeof(saddr);
2074 fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
2075 if (fd < 0 && errno != EINTR) {
2076 return;
2077 } else if (fd >= 0) {
2078 break;
2079 }
2080 }
7a9f6e4a 2081 s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1);
63a01ef8
AL
2082 if (!s1) {
2083 closesocket(fd);
2084 } else {
2085 snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
2086 "socket: connection from %s:%d",
2087 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2088 }
2089}
2090
7a9f6e4a
AL
2091static int net_socket_listen_init(VLANState *vlan,
2092 const char *model,
2093 const char *name,
bf38c1a0 2094 const char *host_str)
63a01ef8
AL
2095{
2096 NetSocketListenState *s;
2097 int fd, val, ret;
2098 struct sockaddr_in saddr;
2099
2100 if (parse_host_port(&saddr, host_str) < 0)
2101 return -1;
2102
2103 s = qemu_mallocz(sizeof(NetSocketListenState));
63a01ef8
AL
2104
2105 fd = socket(PF_INET, SOCK_STREAM, 0);
2106 if (fd < 0) {
2107 perror("socket");
2108 return -1;
2109 }
2110 socket_set_nonblock(fd);
2111
2112 /* allow fast reuse */
2113 val = 1;
2114 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
2115
2116 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2117 if (ret < 0) {
2118 perror("bind");
2119 return -1;
2120 }
2121 ret = listen(fd, 0);
2122 if (ret < 0) {
2123 perror("listen");
2124 return -1;
2125 }
2126 s->vlan = vlan;
02374aa0
MM
2127 s->model = qemu_strdup(model);
2128 s->name = name ? qemu_strdup(name) : NULL;
63a01ef8
AL
2129 s->fd = fd;
2130 qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
2131 return 0;
2132}
2133
7a9f6e4a
AL
2134static int net_socket_connect_init(VLANState *vlan,
2135 const char *model,
2136 const char *name,
bf38c1a0 2137 const char *host_str)
63a01ef8
AL
2138{
2139 NetSocketState *s;
2140 int fd, connected, ret, err;
2141 struct sockaddr_in saddr;
2142
2143 if (parse_host_port(&saddr, host_str) < 0)
2144 return -1;
2145
2146 fd = socket(PF_INET, SOCK_STREAM, 0);
2147 if (fd < 0) {
2148 perror("socket");
2149 return -1;
2150 }
2151 socket_set_nonblock(fd);
2152
2153 connected = 0;
2154 for(;;) {
2155 ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
2156 if (ret < 0) {
2157 err = socket_error();
2158 if (err == EINTR || err == EWOULDBLOCK) {
2159 } else if (err == EINPROGRESS) {
2160 break;
2161#ifdef _WIN32
2162 } else if (err == WSAEALREADY) {
2163 break;
2164#endif
2165 } else {
2166 perror("connect");
2167 closesocket(fd);
2168 return -1;
2169 }
2170 } else {
2171 connected = 1;
2172 break;
2173 }
2174 }
7a9f6e4a 2175 s = net_socket_fd_init(vlan, model, name, fd, connected);
63a01ef8
AL
2176 if (!s)
2177 return -1;
2178 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2179 "socket: connect to %s:%d",
2180 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2181 return 0;
2182}
2183
7a9f6e4a
AL
2184static int net_socket_mcast_init(VLANState *vlan,
2185 const char *model,
2186 const char *name,
bf38c1a0 2187 const char *host_str)
63a01ef8
AL
2188{
2189 NetSocketState *s;
2190 int fd;
2191 struct sockaddr_in saddr;
2192
2193 if (parse_host_port(&saddr, host_str) < 0)
2194 return -1;
2195
2196
2197 fd = net_socket_mcast_create(&saddr);
2198 if (fd < 0)
2199 return -1;
2200
7a9f6e4a 2201 s = net_socket_fd_init(vlan, model, name, fd, 0);
63a01ef8
AL
2202 if (!s)
2203 return -1;
2204
2205 s->dgram_dst = saddr;
2206
2207 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
2208 "socket: mcast=%s:%d",
2209 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
2210 return 0;
2211
2212}
2213
bb9ea79e
AL
2214typedef struct DumpState {
2215 VLANClientState *pcap_vc;
2216 int fd;
2217 int pcap_caplen;
2218} DumpState;
2219
2220#define PCAP_MAGIC 0xa1b2c3d4
2221
2222struct pcap_file_hdr {
2223 uint32_t magic;
2224 uint16_t version_major;
2225 uint16_t version_minor;
2226 int32_t thiszone;
2227 uint32_t sigfigs;
2228 uint32_t snaplen;
2229 uint32_t linktype;
2230};
2231
2232struct pcap_sf_pkthdr {
2233 struct {
2234 int32_t tv_sec;
2235 int32_t tv_usec;
2236 } ts;
2237 uint32_t caplen;
2238 uint32_t len;
2239};
2240
4f1c942b 2241static ssize_t dump_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
bb9ea79e 2242{
e3f5ec2b 2243 DumpState *s = vc->opaque;
bb9ea79e
AL
2244 struct pcap_sf_pkthdr hdr;
2245 int64_t ts;
2246 int caplen;
2247
2248 /* Early return in case of previous error. */
2249 if (s->fd < 0) {
4f1c942b 2250 return size;
bb9ea79e
AL
2251 }
2252
6ee093c9 2253 ts = muldiv64(qemu_get_clock(vm_clock), 1000000, get_ticks_per_sec());
bb9ea79e
AL
2254 caplen = size > s->pcap_caplen ? s->pcap_caplen : size;
2255
37cb6fc3 2256 hdr.ts.tv_sec = ts / 1000000;
bb9ea79e
AL
2257 hdr.ts.tv_usec = ts % 1000000;
2258 hdr.caplen = caplen;
2259 hdr.len = size;
2260 if (write(s->fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
2261 write(s->fd, buf, caplen) != caplen) {
2262 qemu_log("-net dump write error - stop dump\n");
2263 close(s->fd);
2264 s->fd = -1;
2265 }
4f1c942b
MM
2266
2267 return size;
bb9ea79e
AL
2268}
2269
2270static void net_dump_cleanup(VLANClientState *vc)
2271{
2272 DumpState *s = vc->opaque;
2273
2274 close(s->fd);
2275 qemu_free(s);
2276}
2277
10ae5a7a 2278static int net_dump_init(Monitor *mon, VLANState *vlan, const char *device,
bb9ea79e
AL
2279 const char *name, const char *filename, int len)
2280{
2281 struct pcap_file_hdr hdr;
2282 DumpState *s;
2283
2284 s = qemu_malloc(sizeof(DumpState));
2285
024431b3 2286 s->fd = open(filename, O_CREAT | O_WRONLY | O_BINARY, 0644);
bb9ea79e 2287 if (s->fd < 0) {
10ae5a7a 2288 config_error(mon, "-net dump: can't open %s\n", filename);
bb9ea79e
AL
2289 return -1;
2290 }
2291
2292 s->pcap_caplen = len;
2293
2294 hdr.magic = PCAP_MAGIC;
2295 hdr.version_major = 2;
2296 hdr.version_minor = 4;
2297 hdr.thiszone = 0;
2298 hdr.sigfigs = 0;
2299 hdr.snaplen = s->pcap_caplen;
2300 hdr.linktype = 1;
2301
2302 if (write(s->fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
10ae5a7a 2303 config_error(mon, "-net dump write error: %s\n", strerror(errno));
bb9ea79e
AL
2304 close(s->fd);
2305 qemu_free(s);
2306 return -1;
2307 }
2308
463af534 2309 s->pcap_vc = qemu_new_vlan_client(vlan, device, name, NULL, dump_receive, NULL,
bb9ea79e
AL
2310 net_dump_cleanup, s);
2311 snprintf(s->pcap_vc->info_str, sizeof(s->pcap_vc->info_str),
2312 "dump to %s (len=%d)", filename, len);
2313 return 0;
2314}
2315
63a01ef8 2316/* find or alloc a new VLAN */
1a609520 2317VLANState *qemu_find_vlan(int id, int allocate)
63a01ef8
AL
2318{
2319 VLANState **pvlan, *vlan;
2320 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
2321 if (vlan->id == id)
2322 return vlan;
2323 }
1a609520
JK
2324 if (!allocate) {
2325 return NULL;
2326 }
63a01ef8 2327 vlan = qemu_mallocz(sizeof(VLANState));
63a01ef8 2328 vlan->id = id;
72cf2d4f 2329 QTAILQ_INIT(&vlan->send_queue);
63a01ef8
AL
2330 vlan->next = NULL;
2331 pvlan = &first_vlan;
2332 while (*pvlan != NULL)
2333 pvlan = &(*pvlan)->next;
2334 *pvlan = vlan;
2335 return vlan;
2336}
2337
7697079b
AL
2338static int nic_get_free_idx(void)
2339{
2340 int index;
2341
2342 for (index = 0; index < MAX_NICS; index++)
2343 if (!nd_table[index].used)
2344 return index;
2345 return -1;
2346}
2347
07caea31
MA
2348int qemu_show_nic_models(const char *arg, const char *const *models)
2349{
2350 int i;
2351
2352 if (!arg || strcmp(arg, "?"))
2353 return 0;
2354
2355 fprintf(stderr, "qemu: Supported NIC models: ");
2356 for (i = 0 ; models[i]; i++)
2357 fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
2358 return 1;
2359}
2360
d07f22c5
AL
2361void qemu_check_nic_model(NICInfo *nd, const char *model)
2362{
2363 const char *models[2];
2364
2365 models[0] = model;
2366 models[1] = NULL;
2367
07caea31
MA
2368 if (qemu_show_nic_models(nd->model, models))
2369 exit(0);
2370 if (qemu_find_nic_model(nd, models, model) < 0)
2371 exit(1);
d07f22c5
AL
2372}
2373
07caea31
MA
2374int qemu_find_nic_model(NICInfo *nd, const char * const *models,
2375 const char *default_model)
d07f22c5 2376{
07caea31 2377 int i;
d07f22c5
AL
2378
2379 if (!nd->model)
32a8e14a 2380 nd->model = qemu_strdup(default_model);
d07f22c5 2381
07caea31
MA
2382 for (i = 0 ; models[i]; i++) {
2383 if (strcmp(nd->model, models[i]) == 0)
2384 return i;
d07f22c5
AL
2385 }
2386
07caea31
MA
2387 qemu_error("qemu: Unsupported NIC model: %s\n", nd->model);
2388 return -1;
d07f22c5
AL
2389}
2390
c1d6eed7
MM
2391static int net_handle_fd_param(Monitor *mon, const char *param)
2392{
2393 if (!qemu_isdigit(param[0])) {
2394 int fd;
2395
2396 fd = monitor_get_fd(mon, param);
2397 if (fd == -1) {
2398 config_error(mon, "No file descriptor named %s found", param);
2399 return -1;
2400 }
2401
2402 return fd;
2403 } else {
2404 return strtol(param, NULL, 0);
2405 }
2406}
2407
10ae5a7a 2408int net_client_init(Monitor *mon, const char *device, const char *p)
63a01ef8
AL
2409{
2410 char buf[1024];
2411 int vlan_id, ret;
2412 VLANState *vlan;
7a9f6e4a 2413 char *name = NULL;
63a01ef8
AL
2414
2415 vlan_id = 0;
2416 if (get_param_value(buf, sizeof(buf), "vlan", p)) {
2417 vlan_id = strtol(buf, NULL, 0);
2418 }
1a609520 2419 vlan = qemu_find_vlan(vlan_id, 1);
9036de1a 2420
7a9f6e4a 2421 if (get_param_value(buf, sizeof(buf), "name", p)) {
10ae5a7a 2422 name = qemu_strdup(buf);
7a9f6e4a 2423 }
63a01ef8 2424 if (!strcmp(device, "nic")) {
8e4416af 2425 static const char * const nic_params[] = {
eb54b6dc 2426 "vlan", "name", "macaddr", "model", "addr", "id", "vectors", NULL
8e4416af 2427 };
63a01ef8
AL
2428 NICInfo *nd;
2429 uint8_t *macaddr;
7697079b 2430 int idx = nic_get_free_idx();
63a01ef8 2431
0aa7a205 2432 if (check_params(buf, sizeof(buf), nic_params, p) < 0) {
10ae5a7a
JK
2433 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
2434 ret = -1;
2435 goto out;
8e4416af 2436 }
7697079b 2437 if (idx == -1 || nb_nics >= MAX_NICS) {
10ae5a7a 2438 config_error(mon, "Too Many NICs\n");
771f1339
AL
2439 ret = -1;
2440 goto out;
63a01ef8 2441 }
7697079b 2442 nd = &nd_table[idx];
d2cffe30 2443 memset(nd, 0, sizeof(*nd));
63a01ef8
AL
2444 macaddr = nd->macaddr;
2445 macaddr[0] = 0x52;
2446 macaddr[1] = 0x54;
2447 macaddr[2] = 0x00;
2448 macaddr[3] = 0x12;
2449 macaddr[4] = 0x34;
7697079b 2450 macaddr[5] = 0x56 + idx;
63a01ef8
AL
2451
2452 if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
2453 if (parse_macaddr(macaddr, buf) < 0) {
10ae5a7a 2454 config_error(mon, "invalid syntax for ethernet address\n");
771f1339
AL
2455 ret = -1;
2456 goto out;
63a01ef8
AL
2457 }
2458 }
2459 if (get_param_value(buf, sizeof(buf), "model", p)) {
32a8e14a 2460 nd->model = qemu_strdup(buf);
63a01ef8 2461 }
5607c388 2462 if (get_param_value(buf, sizeof(buf), "addr", p)) {
32a8e14a 2463 nd->devaddr = qemu_strdup(buf);
5607c388 2464 }
eb54b6dc 2465 if (get_param_value(buf, sizeof(buf), "id", p)) {
32a8e14a 2466 nd->id = qemu_strdup(buf);
eb54b6dc 2467 }
ffe6370c
MT
2468 nd->nvectors = NIC_NVECTORS_UNSPECIFIED;
2469 if (get_param_value(buf, sizeof(buf), "vectors", p)) {
2470 char *endptr;
2471 long vectors = strtol(buf, &endptr, 0);
2472 if (*endptr) {
2473 config_error(mon, "invalid syntax for # of vectors\n");
2474 ret = -1;
2475 goto out;
2476 }
2477 if (vectors < 0 || vectors > 0x7ffffff) {
2478 config_error(mon, "invalid # of vectors\n");
2479 ret = -1;
2480 goto out;
2481 }
2482 nd->nvectors = vectors;
2483 }
63a01ef8 2484 nd->vlan = vlan;
7a9f6e4a 2485 nd->name = name;
7697079b 2486 nd->used = 1;
7a9f6e4a 2487 name = NULL;
63a01ef8
AL
2488 nb_nics++;
2489 vlan->nb_guest_devs++;
4d73cd3b 2490 ret = idx;
63a01ef8
AL
2491 } else
2492 if (!strcmp(device, "none")) {
8e4416af 2493 if (*p != '\0') {
10ae5a7a
JK
2494 config_error(mon, "'none' takes no parameters\n");
2495 ret = -1;
2496 goto out;
8e4416af 2497 }
63a01ef8
AL
2498 /* does nothing. It is needed to signal that no network cards
2499 are wanted */
2500 ret = 0;
2501 } else
2502#ifdef CONFIG_SLIRP
2503 if (!strcmp(device, "user")) {
8e4416af 2504 static const char * const slirp_params[] = {
c92ef6a2
JK
2505 "vlan", "name", "hostname", "restrict", "ip", "net", "host",
2506 "tftp", "bootfile", "dhcpstart", "dns", "smb", "smbserver",
2507 "hostfwd", "guestfwd", NULL
8e4416af 2508 };
ad196a9d 2509 struct slirp_config_str *config;
c92ef6a2
JK
2510 int restricted = 0;
2511 char *vnet = NULL;
2512 char *vhost = NULL;
2513 char *vhostname = NULL;
ad196a9d
JK
2514 char *tftp_export = NULL;
2515 char *bootfile = NULL;
c92ef6a2
JK
2516 char *vdhcp_start = NULL;
2517 char *vnamesrv = NULL;
ad196a9d 2518 char *smb_export = NULL;
c92ef6a2 2519 char *vsmbsrv = NULL;
ad196a9d 2520 const char *q;
b8e8af38 2521
0aa7a205 2522 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {
10ae5a7a
JK
2523 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
2524 ret = -1;
2525 goto out;
8e4416af 2526 }
c92ef6a2 2527 if (get_param_value(buf, sizeof(buf), "ip", p)) {
3da6abd4 2528 int vnet_buflen = strlen(buf) + strlen("/24") + 1;
c92ef6a2 2529 /* emulate legacy parameter */
3da6abd4
BS
2530 vnet = qemu_malloc(vnet_buflen);
2531 pstrcpy(vnet, vnet_buflen, buf);
2532 pstrcat(vnet, vnet_buflen, "/24");
c92ef6a2
JK
2533 }
2534 if (get_param_value(buf, sizeof(buf), "net", p)) {
2535 vnet = qemu_strdup(buf);
2536 }
2537 if (get_param_value(buf, sizeof(buf), "host", p)) {
2538 vhost = qemu_strdup(buf);
2539 }
63a01ef8 2540 if (get_param_value(buf, sizeof(buf), "hostname", p)) {
c92ef6a2 2541 vhostname = qemu_strdup(buf);
63a01ef8 2542 }
49ec9b40 2543 if (get_param_value(buf, sizeof(buf), "restrict", p)) {
b8e8af38 2544 restricted = (buf[0] == 'y') ? 1 : 0;
49ec9b40 2545 }
c92ef6a2
JK
2546 if (get_param_value(buf, sizeof(buf), "dhcpstart", p)) {
2547 vdhcp_start = qemu_strdup(buf);
2548 }
2549 if (get_param_value(buf, sizeof(buf), "dns", p)) {
2550 vnamesrv = qemu_strdup(buf);
49ec9b40 2551 }
ad196a9d
JK
2552 if (get_param_value(buf, sizeof(buf), "tftp", p)) {
2553 tftp_export = qemu_strdup(buf);
2554 }
2555 if (get_param_value(buf, sizeof(buf), "bootfile", p)) {
2556 bootfile = qemu_strdup(buf);
2557 }
2558 if (get_param_value(buf, sizeof(buf), "smb", p)) {
2559 smb_export = qemu_strdup(buf);
c92ef6a2
JK
2560 if (get_param_value(buf, sizeof(buf), "smbserver", p)) {
2561 vsmbsrv = qemu_strdup(buf);
2562 }
ad196a9d
JK
2563 }
2564 q = p;
2565 while (1) {
2566 config = qemu_malloc(sizeof(*config));
2567 if (!get_next_param_value(config->str, sizeof(config->str),
c92ef6a2 2568 "hostfwd", &q)) {
ad196a9d
JK
2569 break;
2570 }
c92ef6a2 2571 config->flags = SLIRP_CFG_HOSTFWD;
ad196a9d
JK
2572 config->next = slirp_configs;
2573 slirp_configs = config;
2574 config = NULL;
2575 }
2576 q = p;
2577 while (1) {
2578 config = qemu_malloc(sizeof(*config));
2579 if (!get_next_param_value(config->str, sizeof(config->str),
c92ef6a2 2580 "guestfwd", &q)) {
ad196a9d
JK
2581 break;
2582 }
2583 config->flags = 0;
2584 config->next = slirp_configs;
2585 slirp_configs = config;
2586 config = NULL;
2587 }
2588 qemu_free(config);
63a01ef8 2589 vlan->nb_host_devs++;
c92ef6a2
JK
2590 ret = net_slirp_init(mon, vlan, device, name, restricted, vnet, vhost,
2591 vhostname, tftp_export, bootfile, vdhcp_start,
2592 vnamesrv, smb_export, vsmbsrv);
3a179c66
MA
2593 while (slirp_configs) {
2594 config = slirp_configs;
2595 slirp_configs = config->next;
2596 qemu_free(config);
2597 }
c92ef6a2
JK
2598 qemu_free(vnet);
2599 qemu_free(vhost);
2600 qemu_free(vhostname);
ad196a9d
JK
2601 qemu_free(tftp_export);
2602 qemu_free(bootfile);
c92ef6a2
JK
2603 qemu_free(vdhcp_start);
2604 qemu_free(vnamesrv);
ad196a9d 2605 qemu_free(smb_export);
c92ef6a2 2606 qemu_free(vsmbsrv);
8ca9217d 2607 } else if (!strcmp(device, "channel")) {
72cf2d4f 2608 if (QTAILQ_EMPTY(&slirp_stacks)) {
ad196a9d
JK
2609 struct slirp_config_str *config;
2610
2611 config = qemu_malloc(sizeof(*config));
2612 pstrcpy(config->str, sizeof(config->str), p);
c92ef6a2 2613 config->flags = SLIRP_CFG_LEGACY;
ad196a9d
JK
2614 config->next = slirp_configs;
2615 slirp_configs = config;
2616 } else {
72cf2d4f 2617 slirp_guestfwd(QTAILQ_FIRST(&slirp_stacks), mon, p, 1);
8ca9217d 2618 }
8ca9217d 2619 ret = 0;
63a01ef8
AL
2620 } else
2621#endif
2622#ifdef _WIN32
2623 if (!strcmp(device, "tap")) {
8e4416af
AL
2624 static const char * const tap_params[] = {
2625 "vlan", "name", "ifname", NULL
2626 };
63a01ef8 2627 char ifname[64];
8e4416af 2628
0aa7a205 2629 if (check_params(buf, sizeof(buf), tap_params, p) < 0) {
10ae5a7a
JK
2630 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
2631 ret = -1;
2632 goto out;
8e4416af 2633 }
63a01ef8 2634 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
10ae5a7a 2635 config_error(mon, "tap: no interface name\n");
771f1339
AL
2636 ret = -1;
2637 goto out;
63a01ef8
AL
2638 }
2639 vlan->nb_host_devs++;
7a9f6e4a 2640 ret = tap_win32_init(vlan, device, name, ifname);
63a01ef8 2641 } else
b29fe3ed 2642#elif defined (_AIX)
63a01ef8
AL
2643#else
2644 if (!strcmp(device, "tap")) {
0aa7a205 2645 char ifname[64], chkbuf[64];
63a01ef8 2646 char setup_script[1024], down_script[1024];
4a77b25e 2647 TAPState *s;
63a01ef8
AL
2648 int fd;
2649 vlan->nb_host_devs++;
2650 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
0df0ff6d
MM
2651 static const char * const fd_params[] = {
2652 "vlan", "name", "fd", "sndbuf", NULL
2653 };
c1d6eed7 2654 ret = -1;
0aa7a205 2655 if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
10ae5a7a 2656 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
10ae5a7a 2657 goto out;
8e4416af 2658 }
c1d6eed7
MM
2659 fd = net_handle_fd_param(mon, buf);
2660 if (fd == -1) {
2661 goto out;
2662 }
63a01ef8 2663 fcntl(fd, F_SETFL, O_NONBLOCK);
4a77b25e 2664 s = net_tap_fd_init(vlan, device, name, fd);
c1d6eed7
MM
2665 if (!s) {
2666 close(fd);
2667 }
63a01ef8 2668 } else {
8e4416af 2669 static const char * const tap_params[] = {
0df0ff6d 2670 "vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL
8e4416af 2671 };
0aa7a205 2672 if (check_params(chkbuf, sizeof(chkbuf), tap_params, p) < 0) {
10ae5a7a
JK
2673 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
2674 ret = -1;
2675 goto out;
8e4416af 2676 }
63a01ef8
AL
2677 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
2678 ifname[0] = '\0';
2679 }
2680 if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
2681 pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
2682 }
2683 if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
2684 pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
2685 }
4a77b25e
MM
2686 s = net_tap_init(vlan, device, name, ifname, setup_script, down_script);
2687 }
2688 if (s != NULL) {
fc5b81d1 2689 const char *sndbuf_str = NULL;
0df0ff6d 2690 if (get_param_value(buf, sizeof(buf), "sndbuf", p)) {
fc5b81d1 2691 sndbuf_str = buf;
0df0ff6d 2692 }
fc5b81d1 2693 tap_set_sndbuf(s, sndbuf_str, mon);
4a77b25e
MM
2694 ret = 0;
2695 } else {
2696 ret = -1;
63a01ef8
AL
2697 }
2698 } else
2699#endif
2700 if (!strcmp(device, "socket")) {
0aa7a205 2701 char chkbuf[64];
63a01ef8 2702 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
0df0ff6d
MM
2703 static const char * const fd_params[] = {
2704 "vlan", "name", "fd", NULL
2705 };
63a01ef8 2706 int fd;
c1d6eed7 2707 ret = -1;
0aa7a205 2708 if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
10ae5a7a 2709 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
10ae5a7a 2710 goto out;
8e4416af 2711 }
c1d6eed7
MM
2712 fd = net_handle_fd_param(mon, buf);
2713 if (fd == -1) {
2714 goto out;
2715 }
2716 if (!net_socket_fd_init(vlan, device, name, fd, 1)) {
2717 close(fd);
2718 goto out;
2719 }
2720 ret = 0;
63a01ef8 2721 } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
8e4416af
AL
2722 static const char * const listen_params[] = {
2723 "vlan", "name", "listen", NULL
2724 };
0aa7a205 2725 if (check_params(chkbuf, sizeof(chkbuf), listen_params, p) < 0) {
10ae5a7a
JK
2726 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
2727 ret = -1;
2728 goto out;
8e4416af 2729 }
7a9f6e4a 2730 ret = net_socket_listen_init(vlan, device, name, buf);
63a01ef8 2731 } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
8e4416af
AL
2732 static const char * const connect_params[] = {
2733 "vlan", "name", "connect", NULL
2734 };
0aa7a205 2735 if (check_params(chkbuf, sizeof(chkbuf), connect_params, p) < 0) {
10ae5a7a
JK
2736 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
2737 ret = -1;
2738 goto out;
8e4416af 2739 }
7a9f6e4a 2740 ret = net_socket_connect_init(vlan, device, name, buf);
63a01ef8 2741 } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
8e4416af
AL
2742 static const char * const mcast_params[] = {
2743 "vlan", "name", "mcast", NULL
2744 };
0aa7a205 2745 if (check_params(chkbuf, sizeof(chkbuf), mcast_params, p) < 0) {
10ae5a7a
JK
2746 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
2747 ret = -1;
2748 goto out;
8e4416af 2749 }
7a9f6e4a 2750 ret = net_socket_mcast_init(vlan, device, name, buf);
63a01ef8 2751 } else {
10ae5a7a 2752 config_error(mon, "Unknown socket options: %s\n", p);
771f1339
AL
2753 ret = -1;
2754 goto out;
63a01ef8
AL
2755 }
2756 vlan->nb_host_devs++;
2757 } else
2758#ifdef CONFIG_VDE
2759 if (!strcmp(device, "vde")) {
8e4416af
AL
2760 static const char * const vde_params[] = {
2761 "vlan", "name", "sock", "port", "group", "mode", NULL
2762 };
63a01ef8
AL
2763 char vde_sock[1024], vde_group[512];
2764 int vde_port, vde_mode;
8e4416af 2765
0aa7a205 2766 if (check_params(buf, sizeof(buf), vde_params, p) < 0) {
10ae5a7a
JK
2767 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
2768 ret = -1;
2769 goto out;
8e4416af 2770 }
63a01ef8
AL
2771 vlan->nb_host_devs++;
2772 if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
2773 vde_sock[0] = '\0';
2774 }
2775 if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
2776 vde_port = strtol(buf, NULL, 10);
2777 } else {
2778 vde_port = 0;
2779 }
2780 if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
2781 vde_group[0] = '\0';
2782 }
2783 if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
2784 vde_mode = strtol(buf, NULL, 8);
2785 } else {
2786 vde_mode = 0700;
2787 }
7a9f6e4a 2788 ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
63a01ef8
AL
2789 } else
2790#endif
bb9ea79e
AL
2791 if (!strcmp(device, "dump")) {
2792 int len = 65536;
2793
2794 if (get_param_value(buf, sizeof(buf), "len", p) > 0) {
2795 len = strtol(buf, NULL, 0);
2796 }
2797 if (!get_param_value(buf, sizeof(buf), "file", p)) {
2798 snprintf(buf, sizeof(buf), "qemu-vlan%d.pcap", vlan_id);
2799 }
10ae5a7a 2800 ret = net_dump_init(mon, vlan, device, name, buf, len);
bb9ea79e 2801 } else {
10ae5a7a 2802 config_error(mon, "Unknown network device: %s\n", device);
771f1339
AL
2803 ret = -1;
2804 goto out;
63a01ef8
AL
2805 }
2806 if (ret < 0) {
10ae5a7a 2807 config_error(mon, "Could not initialize device '%s'\n", device);
63a01ef8 2808 }
771f1339 2809out:
10ae5a7a 2810 qemu_free(name);
63a01ef8
AL
2811 return ret;
2812}
2813
8b13c4a7
AL
2814void net_client_uninit(NICInfo *nd)
2815{
2816 nd->vlan->nb_guest_devs--;
2817 nb_nics--;
a9796703 2818
9203f520
MM
2819 qemu_free(nd->model);
2820 qemu_free(nd->name);
2821 qemu_free(nd->devaddr);
2822 qemu_free(nd->id);
a9796703 2823
d2cffe30 2824 nd->used = 0;
8b13c4a7
AL
2825}
2826
6f338c34
AL
2827static int net_host_check_device(const char *device)
2828{
2829 int i;
bb9ea79e 2830 const char *valid_param_list[] = { "tap", "socket", "dump"
6f338c34
AL
2831#ifdef CONFIG_SLIRP
2832 ,"user"
2833#endif
2834#ifdef CONFIG_VDE
2835 ,"vde"
2836#endif
2837 };
2838 for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) {
2839 if (!strncmp(valid_param_list[i], device,
2840 strlen(valid_param_list[i])))
2841 return 1;
2842 }
2843
2844 return 0;
2845}
2846
f18c16de 2847void net_host_device_add(Monitor *mon, const QDict *qdict)
6f338c34 2848{
f18c16de
LC
2849 const char *device = qdict_get_str(qdict, "device");
2850 const char *opts = qdict_get_try_str(qdict, "opts");
2851
6f338c34 2852 if (!net_host_check_device(device)) {
376253ec 2853 monitor_printf(mon, "invalid host network device %s\n", device);
6f338c34
AL
2854 return;
2855 }
10ae5a7a 2856 if (net_client_init(mon, device, opts ? opts : "") < 0) {
5c8be678
AL
2857 monitor_printf(mon, "adding host network device %s failed\n", device);
2858 }
6f338c34
AL
2859}
2860
f18c16de 2861void net_host_device_remove(Monitor *mon, const QDict *qdict)
6f338c34 2862{
6f338c34 2863 VLANClientState *vc;
f18c16de
LC
2864 int vlan_id = qdict_get_int(qdict, "vlan_id");
2865 const char *device = qdict_get_str(qdict, "device");
6f338c34 2866
1a609520 2867 vc = qemu_find_vlan_client_by_name(mon, vlan_id, device);
6f338c34 2868 if (!vc) {
6f338c34
AL
2869 return;
2870 }
e8f1f9db
AL
2871 if (!net_host_check_device(vc->model)) {
2872 monitor_printf(mon, "invalid host network device %s\n", device);
2873 return;
2874 }
6f338c34
AL
2875 qemu_del_vlan_client(vc);
2876}
2877
63a01ef8
AL
2878int net_client_parse(const char *str)
2879{
2880 const char *p;
2881 char *q;
2882 char device[64];
2883
2884 p = str;
2885 q = device;
2886 while (*p != '\0' && *p != ',') {
2887 if ((q - device) < sizeof(device) - 1)
2888 *q++ = *p;
2889 p++;
2890 }
2891 *q = '\0';
2892 if (*p == ',')
2893 p++;
2894
10ae5a7a 2895 return net_client_init(NULL, device, p);
63a01ef8
AL
2896}
2897
406c8df3
GC
2898void net_set_boot_mask(int net_boot_mask)
2899{
2900 int i;
2901
2902 /* Only the first four NICs may be bootable */
2903 net_boot_mask = net_boot_mask & 0xF;
2904
2905 for (i = 0; i < nb_nics; i++) {
2906 if (net_boot_mask & (1 << i)) {
2907 nd_table[i].bootable = 1;
2908 net_boot_mask &= ~(1 << i);
2909 }
2910 }
2911
2912 if (net_boot_mask) {
2913 fprintf(stderr, "Cannot boot from non-existent NIC\n");
2914 exit(1);
2915 }
2916}
2917
376253ec 2918void do_info_network(Monitor *mon)
63a01ef8
AL
2919{
2920 VLANState *vlan;
2921 VLANClientState *vc;
2922
2923 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
376253ec 2924 monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
63a01ef8 2925 for(vc = vlan->first_client; vc != NULL; vc = vc->next)
376253ec 2926 monitor_printf(mon, " %s: %s\n", vc->name, vc->info_str);
63a01ef8
AL
2927 }
2928}
2929
f18c16de 2930void do_set_link(Monitor *mon, const QDict *qdict)
436e5e53
AL
2931{
2932 VLANState *vlan;
2933 VLANClientState *vc = NULL;
f18c16de
LC
2934 const char *name = qdict_get_str(qdict, "name");
2935 const char *up_or_down = qdict_get_str(qdict, "up_or_down");
436e5e53
AL
2936
2937 for (vlan = first_vlan; vlan != NULL; vlan = vlan->next)
2938 for (vc = vlan->first_client; vc != NULL; vc = vc->next)
2939 if (strcmp(vc->name, name) == 0)
dd5de373
EI
2940 goto done;
2941done:
436e5e53
AL
2942
2943 if (!vc) {
7dc3fa09 2944 monitor_printf(mon, "could not find network device '%s'\n", name);
c3cf0d3f 2945 return;
436e5e53
AL
2946 }
2947
2948 if (strcmp(up_or_down, "up") == 0)
2949 vc->link_down = 0;
2950 else if (strcmp(up_or_down, "down") == 0)
2951 vc->link_down = 1;
2952 else
376253ec
AL
2953 monitor_printf(mon, "invalid link status '%s'; only 'up' or 'down' "
2954 "valid\n", up_or_down);
436e5e53 2955
34b25ca7
AL
2956 if (vc->link_status_changed)
2957 vc->link_status_changed(vc);
436e5e53
AL
2958}
2959
63a01ef8
AL
2960void net_cleanup(void)
2961{
2962 VLANState *vlan;
2963
63a01ef8
AL
2964 /* close network clients */
2965 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
b946a153 2966 VLANClientState *vc = vlan->first_client;
63a01ef8 2967
b946a153
AL
2968 while (vc) {
2969 VLANClientState *next = vc->next;
63a01ef8 2970
b946a153
AL
2971 qemu_del_vlan_client(vc);
2972
2973 vc = next;
63a01ef8
AL
2974 }
2975 }
63a01ef8
AL
2976}
2977
2978void net_client_check(void)
2979{
2980 VLANState *vlan;
2981
2982 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
2983 if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
2984 continue;
2985 if (vlan->nb_guest_devs == 0)
2986 fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
2987 if (vlan->nb_host_devs == 0)
2988 fprintf(stderr,
2989 "Warning: vlan %d is not connected to host network\n",
2990 vlan->id);
2991 }
2992}