#include "config-host.h"
+#ifndef _WIN32
+#include <sys/wait.h>
+#endif
#include "net.h"
#include "monitor.h"
#include "sysemu.h"
};
typedef struct SlirpState {
+ VLANClientState nc;
QTAILQ_ENTRY(SlirpState) entry;
- VLANClientState *vc;
Slirp *slirp;
#ifndef _WIN32
char smb_dir[128];
{
SlirpState *s = opaque;
- return qemu_can_send_packet(s->vc);
+ return qemu_can_send_packet(&s->nc);
}
void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
{
SlirpState *s = opaque;
- qemu_send_packet(s->vc, pkt, pkt_len);
+ qemu_send_packet(&s->nc, pkt, pkt_len);
}
-static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t net_slirp_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
{
- SlirpState *s = vc->opaque;
+ SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
slirp_input(s->slirp, buf, size);
return size;
}
-static void net_slirp_cleanup(VLANClientState *vc)
+static void net_slirp_cleanup(VLANClientState *nc)
{
- SlirpState *s = vc->opaque;
+ SlirpState *s = DO_UPCAST(SlirpState, nc, nc);
slirp_cleanup(s->slirp);
slirp_smb_cleanup(s);
QTAILQ_REMOVE(&slirp_stacks, s, entry);
- qemu_free(s);
}
+static NetClientInfo net_slirp_info = {
+ .type = NET_CLIENT_TYPE_SLIRP,
+ .size = sizeof(SlirpState),
+ .receive = net_slirp_receive,
+ .cleanup = net_slirp_cleanup,
+};
+
static int net_slirp_init(VLANState *vlan, const char *model,
const char *name, int restricted,
const char *vnetwork, const char *vhost,
#ifndef _WIN32
struct in_addr smbsrv = { .s_addr = 0 };
#endif
+ VLANClientState *nc;
SlirpState *s;
char buf[20];
uint32_t addr;
}
#endif
- s = qemu_mallocz(sizeof(SlirpState));
+ nc = qemu_new_net_client(&net_slirp_info, vlan, NULL, model, name);
+
+ snprintf(nc->info_str, sizeof(nc->info_str),
+ "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');
+
+ s = DO_UPCAST(SlirpState, nc, nc);
+
s->slirp = slirp_init(restricted, net, mask, host, vhostname,
tftp_export, bootfile, dhcp, dns, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
if (config->flags & SLIRP_CFG_HOSTFWD) {
if (slirp_hostfwd(s, config->str,
config->flags & SLIRP_CFG_LEGACY) < 0)
- return -1;
+ goto error;
} else {
if (slirp_guestfwd(s, config->str,
config->flags & SLIRP_CFG_LEGACY) < 0)
- return -1;
+ goto error;
}
}
#ifndef _WIN32
}
if (smb_export) {
if (slirp_smb(s, smb_export, smbsrv) < 0)
- return -1;
+ goto error;
}
#endif
- s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SLIRP,
- vlan, NULL, model, name, NULL,
- slirp_receive, NULL, NULL,
- net_slirp_cleanup, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');
return 0;
+
+error:
+ qemu_del_vlan_client(nc);
+ return -1;
}
static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,
const char *stack)
{
- VLANClientState *vc;
if (vlan) {
- vc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
- if (!vc) {
+ VLANClientState *nc;
+ nc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);
+ if (!nc) {
return NULL;
}
- if (strcmp(vc->model, "user")) {
+ if (strcmp(nc->model, "user")) {
monitor_printf(mon, "invalid device specified\n");
return NULL;
}
- return vc->opaque;
+ return DO_UPCAST(SlirpState, nc, nc);
} else {
if (QTAILQ_EMPTY(&slirp_stacks)) {
monitor_printf(mon, "user mode network stack not in use\n");
if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
guest_port) < 0) {
- qemu_error("could not set up host forwarding rule '%s'\n",
- redir_str);
+ error_report("could not set up host forwarding rule '%s'",
+ redir_str);
return -1;
}
return 0;
fail_syntax:
- qemu_error("invalid host forwarding rule '%s'\n", redir_str);
+ error_report("invalid host forwarding rule '%s'", redir_str);
return -1;
}
static void slirp_smb_cleanup(SlirpState *s)
{
char cmd[128];
+ int ret;
if (s->smb_dir[0] != '\0') {
snprintf(cmd, sizeof(cmd), "rm -rf %s", s->smb_dir);
- system(cmd);
+ ret = system(cmd);
+ if (ret == -1 || !WIFEXITED(ret)) {
+ error_report("'%s' failed.", cmd);
+ } else if (WEXITSTATUS(ret)) {
+ error_report("'%s' failed. Error code: %d",
+ cmd, WEXITSTATUS(ret));
+ }
s->smb_dir[0] = '\0';
}
}
snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d",
(long)getpid(), instance++);
if (mkdir(s->smb_dir, 0700) < 0) {
- qemu_error("could not create samba server dir '%s'\n", s->smb_dir);
+ error_report("could not create samba server dir '%s'", s->smb_dir);
return -1;
}
snprintf(smb_conf, sizeof(smb_conf), "%s/%s", s->smb_dir, "smb.conf");
f = fopen(smb_conf, "w");
if (!f) {
slirp_smb_cleanup(s);
- qemu_error("could not create samba server configuration file '%s'\n",
- smb_conf);
+ error_report("could not create samba server configuration file '%s'",
+ smb_conf);
return -1;
}
fprintf(f,
if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
slirp_smb_cleanup(s);
- qemu_error("conflicting/invalid smbserver address\n");
+ error_report("conflicting/invalid smbserver address");
return -1;
}
return 0;
snprintf(buf, sizeof(buf), "guestfwd.tcp:%d", port);
fwd->hd = qemu_chr_open(buf, p, NULL);
if (!fwd->hd) {
- qemu_error("could not open guest forwarding device '%s'\n", buf);
+ error_report("could not open guest forwarding device '%s'", buf);
qemu_free(fwd);
return -1;
}
if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
- qemu_error("conflicting/invalid host:port in guest forwarding "
- "rule '%s'\n", config_str);
+ error_report("conflicting/invalid host:port in guest forwarding "
+ "rule '%s'", config_str);
qemu_free(fwd);
return -1;
}
return 0;
fail_syntax:
- qemu_error("invalid guest forwarding rule '%s'\n", config_str);
+ error_report("invalid guest forwarding rule '%s'", config_str);
return -1;
}
SlirpState *s;
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
- monitor_printf(mon, "VLAN %d (%s):\n", s->vc->vlan->id, s->vc->name);
+ monitor_printf(mon, "VLAN %d (%s):\n",
+ s->nc.vlan ? s->nc.vlan->id : -1,
+ s->nc.name);
slirp_connection_info(s->slirp, mon);
}
}
qemu_free(config);
}
- if (ret != -1 && vlan) {
- vlan->nb_host_devs++;
- }
-
qemu_free(vnet);
return ret;