aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--Makefile.objs4
-rw-r--r--Makefile.target5
-rw-r--r--include/glib-compat.h56
-rw-r--r--net/colo-compare.c11
-rw-r--r--net/colo.c1
-rw-r--r--net/colo.h7
-rw-r--r--net/filter-rewriter.c9
-rw-r--r--net/slirp.c61
-rw-r--r--net/util.h55
-rw-r--r--slirp/Makefile.objs37
-rw-r--r--slirp/arp_table.c12
-rw-r--r--slirp/bootp.c10
-rw-r--r--slirp/cksum.c8
-rw-r--r--slirp/debug.h47
-rw-r--r--slirp/dhcpv6.c17
-rw-r--r--slirp/if.c4
-rw-r--r--slirp/ip.h10
-rw-r--r--slirp/ip6.h3
-rw-r--r--slirp/ip6_icmp.c27
-rw-r--r--slirp/ip6_icmp.h6
-rw-r--r--slirp/ip6_input.c2
-rw-r--r--slirp/ip6_output.c4
-rw-r--r--slirp/ip_icmp.c31
-rw-r--r--slirp/ip_input.c200
-rw-r--r--slirp/libslirp.h27
-rw-r--r--slirp/main.h33
-rw-r--r--slirp/mbuf.c2
-rw-r--r--slirp/mbuf.h1
-rw-r--r--slirp/misc.c286
-rw-r--r--slirp/misc.h13
-rw-r--r--slirp/ncsi.c4
-rw-r--r--slirp/ndp_table.c32
-rw-r--r--slirp/sbuf.h1
-rw-r--r--slirp/slirp.c177
-rw-r--r--slirp/slirp.h45
-rw-r--r--slirp/slirp_config.h86
-rw-r--r--slirp/socket.c53
-rw-r--r--slirp/socket.h2
-rw-r--r--slirp/tcp.h4
-rw-r--r--slirp/tcp_input.c84
-rw-r--r--slirp/tcp_output.c2
-rw-r--r--slirp/tcp_subr.c22
-rw-r--r--slirp/tcp_timer.c2
-rw-r--r--slirp/tftp.c7
-rw-r--r--slirp/trace-events5
-rw-r--r--slirp/udp.c5
-rw-r--r--slirp/udp6.c11
-rw-r--r--stubs/slirp.c2
49 files changed, 603 insertions, 935 deletions
diff --git a/Makefile b/Makefile
index a9ac16d94e..dccba1dca2 100644
--- a/Makefile
+++ b/Makefile
@@ -379,7 +379,8 @@ dummy := $(call unnest-vars,, \
ui-obj-m \
audio-obj-y \
audio-obj-m \
- trace-obj-y)
+ trace-obj-y \
+ slirp-obj-y)
include $(SRC_PATH)/tests/Makefile.include
@@ -452,7 +453,7 @@ CAP_CFLAGS += -DCAPSTONE_HAS_X86
subdir-capstone: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) $(BUILD_DIR)/capstone/$(LIBCAPSTONE))
-$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
+$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) $(slirp-obj-y) \
$(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
diff --git a/Makefile.objs b/Makefile.objs
index 456115992a..67a054b08a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -17,6 +17,7 @@ util-obj-y += $(QAPI_MODULES:%=qapi/qapi-events-%.o)
util-obj-y += qapi/qapi-introspect.o
chardev-obj-y = chardev/
+slirp-obj-$(CONFIG_SLIRP) = slirp/
#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
@@ -79,8 +80,6 @@ common-obj-y += vl.o
vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
common-obj-$(CONFIG_TPM) += tpm.o
-common-obj-$(CONFIG_SLIRP) += slirp/
-
common-obj-y += backends/
common-obj-y += chardev/
@@ -193,6 +192,7 @@ trace-events-subdirs += net
trace-events-subdirs += qapi
trace-events-subdirs += qom
trace-events-subdirs += scsi
+trace-events-subdirs += slirp
trace-events-subdirs += target/arm
trace-events-subdirs += target/i386
trace-events-subdirs += target/mips
diff --git a/Makefile.target b/Makefile.target
index 44ec4b630c..39f72e81be 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -165,6 +165,7 @@ target-obj-y :=
block-obj-y :=
common-obj-y :=
chardev-obj-y :=
+slirp-obj-y :=
include $(SRC_PATH)/Makefile.objs
dummy := $(call unnest-vars,,target-obj-y)
target-obj-y-save := $(target-obj-y)
@@ -177,7 +178,8 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
- common-obj-m)
+ common-obj-m \
+ slirp-obj-y)
target-obj-y := $(target-obj-y-save)
all-obj-y += $(common-obj-y)
all-obj-y += $(target-obj-y)
@@ -186,6 +188,7 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
+all-obj-$(CONFIG_SOFTMMU) += $(slirp-obj-y)
$(QEMU_PROG_BUILD): config-devices.mak
diff --git a/include/glib-compat.h b/include/glib-compat.h
index fdf95a255d..8a078c5288 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -83,6 +83,62 @@ static inline gboolean g_strv_contains_qemu(const gchar *const *strv,
}
#define g_strv_contains(a, b) g_strv_contains_qemu(a, b)
+#if !GLIB_CHECK_VERSION(2, 58, 0)
+typedef struct QemuGSpawnFds {
+ GSpawnChildSetupFunc child_setup;
+ gpointer user_data;
+ gint stdin_fd;
+ gint stdout_fd;
+ gint stderr_fd;
+} QemuGSpawnFds;
+
+static inline void
+qemu_gspawn_fds_setup(gpointer user_data)
+{
+ QemuGSpawnFds *q = (QemuGSpawnFds *)user_data;
+
+ dup2(q->stdin_fd, 0);
+ dup2(q->stdout_fd, 1);
+ dup2(q->stderr_fd, 2);
+ q->child_setup(q->user_data);
+}
+#endif
+
+static inline gboolean
+g_spawn_async_with_fds_qemu(const gchar *working_directory,
+ gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ GSpawnChildSetupFunc child_setup,
+ gpointer user_data,
+ GPid *child_pid,
+ gint stdin_fd,
+ gint stdout_fd,
+ gint stderr_fd,
+ GError **error)
+{
+#if GLIB_CHECK_VERSION(2, 58, 0)
+ return g_spawn_async_with_fds(working_directory, argv, envp, flags,
+ child_setup, user_data,
+ child_pid, stdin_fd, stdout_fd, stderr_fd,
+ error);
+#else
+ QemuGSpawnFds setup = {
+ .child_setup = child_setup,
+ .user_data = user_data,
+ .stdin_fd = stdin_fd,
+ .stdout_fd = stdout_fd,
+ .stderr_fd = stderr_fd,
+ };
+
+ return g_spawn_async(working_directory, argv, envp, flags,
+ qemu_gspawn_fds_setup, &setup,
+ child_pid, error);
+#endif
+}
+
+#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \
+ g_spawn_async_with_fds_qemu(wd, argv, env, f, c, d, p, ifd, ofd, efd, err)
#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0)
/*
diff --git a/net/colo-compare.c b/net/colo-compare.c
index 9156ab3349..3e515f3023 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -30,6 +30,7 @@
#include "net/colo-compare.h"
#include "migration/colo.h"
#include "migration/migration.h"
+#include "util.h"
#define TYPE_COLO_COMPARE "colo-compare"
#define COLO_COMPARE(obj) \
@@ -129,19 +130,19 @@ static int compare_chr_send(CompareState *s,
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
{
- struct tcphdr *atcp, *btcp;
+ struct tcp_hdr *atcp, *btcp;
- atcp = (struct tcphdr *)(a->transport_header);
- btcp = (struct tcphdr *)(b->transport_header);
+ atcp = (struct tcp_hdr *)(a->transport_header);
+ btcp = (struct tcp_hdr *)(b->transport_header);
return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
}
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
{
Packet *pkt = data;
- struct tcphdr *tcphd;
+ struct tcp_hdr *tcphd;
- tcphd = (struct tcphdr *)pkt->transport_header;
+ tcphd = (struct tcp_hdr *)pkt->transport_header;
pkt->tcp_seq = ntohl(tcphd->th_seq);
pkt->tcp_ack = ntohl(tcphd->th_ack);
diff --git a/net/colo.c b/net/colo.c
index 49176bf07b..8196b35837 100644
--- a/net/colo.c
+++ b/net/colo.c
@@ -15,6 +15,7 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "colo.h"
+#include "util.h"
uint32_t connection_key_hash(const void *opaque)
{
diff --git a/net/colo.h b/net/colo.h
index 11c5226488..b21c6830b5 100644
--- a/net/colo.h
+++ b/net/colo.h
@@ -15,10 +15,9 @@
#ifndef QEMU_COLO_PROXY_H
#define QEMU_COLO_PROXY_H
-#include "slirp/slirp.h"
#include "qemu/jhash.h"
#include "qemu/timer.h"
-#include "slirp/tcp.h"
+#include "net/eth.h"
#define HASHTABLE_MAX_SIZE 16384
@@ -81,10 +80,10 @@ typedef struct Connection {
/* the maximum of acknowledgement number in secondary_list queue */
uint32_t sack;
/* offset = secondary_seq - primary_seq */
- tcp_seq offset;
+ uint32_t offset;
int tcp_state; /* TCP FSM state */
- tcp_seq fin_ack_seq; /* the seq of 'fin=1,ack=1' */
+ uint32_t fin_ack_seq; /* the seq of 'fin=1,ack=1' */
} Connection;
uint32_t connection_key_hash(const void *opaque);
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index 2e26839bc2..b464abe5e8 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -22,6 +22,7 @@
#include "net/checksum.h"
#include "net/colo.h"
#include "migration/colo.h"
+#include "util.h"
#define FILTER_COLO_REWRITER(obj) \
OBJECT_CHECK(RewriterState, (obj), TYPE_FILTER_REWRITER)
@@ -73,9 +74,9 @@ static int handle_primary_tcp_pkt(RewriterState *rf,
Connection *conn,
Packet *pkt, ConnectionKey *key)
{
- struct tcphdr *tcp_pkt;
+ struct tcp_hdr *tcp_pkt;
- tcp_pkt = (struct tcphdr *)pkt->transport_header;
+ tcp_pkt = (struct tcp_hdr *)pkt->transport_header;
if (trace_event_get_state_backends(TRACE_COLO_FILTER_REWRITER_DEBUG)) {
trace_colo_filter_rewriter_pkt_info(__func__,
inet_ntoa(pkt->ip->ip_src), inet_ntoa(pkt->ip->ip_dst),
@@ -176,9 +177,9 @@ static int handle_secondary_tcp_pkt(RewriterState *rf,
Connection *conn,
Packet *pkt, ConnectionKey *key)
{
- struct tcphdr *tcp_pkt;
+ struct tcp_hdr *tcp_pkt;
- tcp_pkt = (struct tcphdr *)pkt->transport_header;
+ tcp_pkt = (struct tcp_hdr *)pkt->transport_header;
if (trace_event_get_state_backends(TRACE_COLO_FILTER_REWRITER_DEBUG)) {
trace_colo_filter_rewriter_pkt_info(__func__,
diff --git a/net/slirp.c b/net/slirp.c
index 38ae65e4a9..f98425ee9f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "net/slirp.h"
@@ -37,12 +38,12 @@
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "slirp/libslirp.h"
-#include "slirp/ip6.h"
#include "chardev/char-fe.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
+#include "util.h"
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
{
@@ -99,7 +100,7 @@ static void slirp_smb_cleanup(SlirpState *s);
static inline void slirp_smb_cleanup(SlirpState *s) { }
#endif
-void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
+static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
{
SlirpState *s = opaque;
@@ -140,6 +141,22 @@ static NetClientInfo net_slirp_info = {
.cleanup = net_slirp_cleanup,
};
+static void net_slirp_guest_error(const char *msg)
+{
+ qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
+}
+
+static int64_t net_slirp_clock_get_ns(void)
+{
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+}
+
+static const SlirpCb slirp_cb = {
+ .output = net_slirp_output,
+ .guest_error = net_slirp_guest_error,
+ .clock_get_ns = net_slirp_clock_get_ns,
+};
+
static int net_slirp_init(NetClientState *peer, const char *model,
const char *name, int restricted,
bool ipv4, const char *vnetwork, const char *vhost,
@@ -279,17 +296,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
}
#endif
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
- /* No inet_pton helper before Vista... */
- if (vprefix6) {
- /* Unsupported */
- error_setg(errp, "IPv6 prefix not supported");
- return -1;
- }
- memset(&ip6_prefix, 0, sizeof(ip6_prefix));
- ip6_prefix.s6_addr[0] = 0xfe;
- ip6_prefix.s6_addr[1] = 0xc0;
-#else
if (!vprefix6) {
vprefix6 = "fec0::";
}
@@ -297,7 +303,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
error_setg(errp, "Failed to parse IPv6 prefix");
return -1;
}
-#endif
if (!vprefix6_len) {
vprefix6_len = 64;
@@ -309,10 +314,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
}
if (vhost6) {
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
- error_setg(errp, "IPv6 host not supported");
- return -1;
-#else
if (!inet_pton(AF_INET6, vhost6, &ip6_host)) {
error_setg(errp, "Failed to parse IPv6 host");
return -1;
@@ -321,17 +322,12 @@ static int net_slirp_init(NetClientState *peer, const char *model,
error_setg(errp, "IPv6 Host doesn't belong to network");
return -1;
}
-#endif
} else {
ip6_host = ip6_prefix;
ip6_host.s6_addr[15] |= 2;
}
if (vnameserver6) {
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
- error_setg(errp, "IPv6 DNS not supported");
- return -1;
-#else
if (!inet_pton(AF_INET6, vnameserver6, &ip6_dns)) {
error_setg(errp, "Failed to parse IPv6 DNS");
return -1;
@@ -340,7 +336,6 @@ static int net_slirp_init(NetClientState *peer, const char *model,
error_setg(errp, "IPv6 DNS doesn't belong to network");
return -1;
}
-#endif
} else {
ip6_dns = ip6_prefix;
ip6_dns.s6_addr[15] |= 3;
@@ -378,7 +373,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
ipv6, ip6_prefix, vprefix6_len, ip6_host,
vhostname, tftp_server_name,
tftp_export, bootfile, dhcp,
- dns, ip6_dns, dnssearch, vdomainname, s);
+ dns, ip6_dns, dnssearch, vdomainname,
+ &slirp_cb, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
for (config = slirp_configs; config; config = config->next) {
@@ -708,8 +704,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
g_free(smb_conf);
- if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0 ||
- slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 445) < 0) {
+ if (slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 139) < 0 ||
+ slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 445) < 0) {
slirp_smb_cleanup(s);
g_free(smb_cmdline);
error_setg(errp, "Conflicting/invalid smbserver address");
@@ -773,7 +769,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
- if (slirp_add_exec(s->slirp, 0, &p[4], &server, port) < 0) {
+ if (slirp_add_exec(s->slirp, NULL, &p[4], &server, port) < 0) {
error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
return -1;
@@ -800,7 +796,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
return -1;
}
- if (slirp_add_exec(s->slirp, 3, &fwd->hd, &server, port) < 0) {
+ if (slirp_add_exec(s->slirp, &fwd->hd, NULL, &server, port) < 0) {
error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
g_free(fwd);
@@ -827,10 +823,11 @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
int id;
bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
- monitor_printf(mon, "Hub %d (%s):\n",
+ char *info = slirp_connection_info(s->slirp);
+ monitor_printf(mon, "Hub %d (%s):\n%s",
got_hub_id ? id : -1,
- s->nc.name);
- slirp_connection_info(s->slirp, mon);
+ s->nc.name, info);
+ g_free(info);
}
}
diff --git a/net/util.h b/net/util.h
index 60b73d372d..358185fd50 100644
--- a/net/util.h
+++ b/net/util.h
@@ -26,6 +26,61 @@
#define QEMU_NET_UTIL_H
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#ifdef HOST_WORDS_BIGENDIAN
+ uint8_t ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#else
+ uint8_t ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#endif
+ uint8_t ip_tos; /* type of service */
+ uint16_t ip_len; /* total length */
+ uint16_t ip_id; /* identification */
+ uint16_t ip_off; /* fragment offset field */
+#define IP_DF 0x4000 /* don't fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ uint8_t ip_ttl; /* time to live */
+ uint8_t ip_p; /* protocol */
+ uint16_t ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+} QEMU_PACKED;
+
+static inline bool in6_equal_net(const struct in6_addr *a,
+ const struct in6_addr *b,
+ int prefix_len)
+{
+ if (memcmp(a, b, prefix_len / 8) != 0) {
+ return 0;
+ }
+
+ if (prefix_len % 8 == 0) {
+ return 1;
+ }
+
+ return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
+ == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
+}
+
+#define TCPS_CLOSED 0 /* closed */
+#define TCPS_LISTEN 1 /* listening for connection */
+#define TCPS_SYN_SENT 2 /* active, have sent syn */
+#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
+/* states < TCPS_ESTABLISHED are those where connections not established */
+#define TCPS_ESTABLISHED 4 /* established */
+#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
+/* states > TCPS_CLOSE_WAIT are those where user has closed */
+#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
+#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
+#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
+/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
+#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
+#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
+
int net_parse_macaddr(uint8_t *macaddr, const char *p);
#endif /* QEMU_NET_UTIL_H */
diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 28049b03cd..959558c732 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -1,5 +1,32 @@
-common-obj-y = cksum.o if.o ip_icmp.o ip6_icmp.o ip6_input.o ip6_output.o \
- ip_input.o ip_output.o dnssearch.o dhcpv6.o
-common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-common-obj-y += tcp_subr.o tcp_timer.o udp.o udp6.o bootp.o tftp.o arp_table.o \
- ndp_table.o ncsi.o
+slirp-obj-y = slirp.mo
+
+slirp.mo-objs = \
+ arp_table.o \
+ bootp.o \
+ cksum.o \
+ dhcpv6.o \
+ dnssearch.o \
+ if.o \
+ ip6_icmp.o \
+ ip6_input.o \
+ ip6_output.o \
+ ip_icmp.o \
+ ip_input.o \
+ ip_output.o \
+ mbuf.o \
+ misc.o \
+ ncsi.o \
+ ndp_table.o \
+ sbuf.o \
+ slirp.o \
+ socket.o \
+ tcp_input.o \
+ tcp_output.o \
+ tcp_subr.o \
+ tcp_timer.o \
+ tftp.o \
+ udp.o \
+ udp6.o \
+ $(NULL)
+
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index f81963bb88..bf71b984ad 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -34,9 +34,9 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
DEBUG_CALL("arp_table_add");
DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){.s_addr = ip_addr}));
- DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
- ethaddr[0], ethaddr[1], ethaddr[2],
- ethaddr[3], ethaddr[4], ethaddr[5]));
+ DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+ ethaddr[0], ethaddr[1], ethaddr[2],
+ ethaddr[3], ethaddr[4], ethaddr[5]);
if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
/* Do not register broadcast addresses */
@@ -79,9 +79,9 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
for (i = 0; i < ARP_TABLE_SIZE; i++) {
if (arptbl->table[i].ar_sip == ip_addr) {
memcpy(out_ethaddr, arptbl->table[i].ar_sha, ETH_ALEN);
- DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
- out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
- out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+ DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+ out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+ out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
return 1;
}
}
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 7b1af73c95..4c9a77eb98 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -36,12 +36,7 @@
static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
-#ifdef DEBUG
-#define DPRINTF(fmt, ...) \
-do if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## __VA_ARGS__); fflush(dfd); } while (0)
-#else
-#define DPRINTF(fmt, ...) do{}while(0)
-#endif
+#define DPRINTF(fmt, ...) DEBUG_CALL(fmt, ##__VA_ARGS__)
static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr,
const uint8_t *macaddr)
@@ -167,8 +162,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
if (preq_addr.s_addr != htonl(0L))
DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
- else
+ else {
DPRINTF("\n");
+ }
if (dhcp_msg_type == 0)
dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 6d73abf4a0..84c858fafb 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -70,9 +70,7 @@ int cksum(struct mbuf *m, int len)
if (len < mlen)
mlen = len;
-#ifdef DEBUG
len -= mlen;
-#endif
/*
* Force to even boundary.
*/
@@ -122,12 +120,10 @@ int cksum(struct mbuf *m, int len)
s_util.c[0] = *(uint8_t *)w;
cont:
-#ifdef DEBUG
if (len) {
- DEBUG_ERROR((dfd, "cksum: out of data\n"));
- DEBUG_ERROR((dfd, " len = %d\n", len));
+ DEBUG_ERROR("cksum: out of data");
+ DEBUG_ERROR(" len = %d", len);
}
-#endif
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
diff --git a/slirp/debug.h b/slirp/debug.h
index 6cfa61edb3..269d97d807 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -5,30 +5,37 @@
* terms and conditions of the copyright.
*/
-//#define DEBUG 1
-
-#ifdef DEBUG
+#ifndef DEBUG_H_
+#define DEBUG_H_
#define DBG_CALL 0x1
#define DBG_MISC 0x2
#define DBG_ERROR 0x4
-#define dfd stderr
-
extern int slirp_debug;
-#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); }
-#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); }
-#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); }
-#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); }
-#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); }
-
-#else
-
-#define DEBUG_CALL(x)
-#define DEBUG_ARG(x, y)
-#define DEBUG_ARGS(x)
-#define DEBUG_MISC(x)
-#define DEBUG_ERROR(x)
-
-#endif
+#define DEBUG_CALL(fmt, ...) do { \
+ if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
+ g_debug(fmt "...", ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#define DEBUG_ARG(fmt, ...) do { \
+ if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
+ g_debug(" " fmt, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#define DEBUG_MISC(fmt, ...) do { \
+ if (G_UNLIKELY(slirp_debug & DBG_MISC)) { \
+ g_debug(fmt, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#define DEBUG_ERROR(fmt, ...) do { \
+ if (G_UNLIKELY(slirp_debug & DBG_ERROR)) { \
+ g_debug(fmt, ##__VA_ARGS__); \
+ } \
+} while (0)
+
+#endif /* DEBUG_H_ */
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index d266611e85..752df40536 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -50,7 +50,7 @@ struct requested_infos {
* the odata region, thus the caller must keep odata valid as long as it
* needs to access the requested_infos struct.
*/
-static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
+static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t *odata, int olen,
struct requested_infos *ri)
{
int i, req_opt;
@@ -61,7 +61,7 @@ static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
int len = odata[2] << 8 | odata[3];
if (len + 4 > olen) {
- qemu_log_mask(LOG_GUEST_ERROR, "Guest sent bad DHCPv6 packet!\n");
+ slirp->cb->guest_error("Guest sent bad DHCPv6 packet!");
return -E2BIG;
}
@@ -92,14 +92,14 @@ static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
ri->want_boot_url = true;
break;
default:
- DEBUG_MISC((dfd, "dhcpv6: Unsupported option request %d\n",
- req_opt));
+ DEBUG_MISC("dhcpv6: Unsupported option request %d",
+ req_opt);
}
}
break;
default:
- DEBUG_MISC((dfd, "dhcpv6 info req: Unsupported option %d, len=%d\n",
- option, len));
+ DEBUG_MISC("dhcpv6 info req: Unsupported option %d, len=%d",
+ option, len);
}
odata += len + 4;
@@ -121,7 +121,7 @@ static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas,
struct mbuf *m;
uint8_t *resp;
- if (dhcpv6_parse_info_request(odata, olen, &ri) < 0) {
+ if (dhcpv6_parse_info_request(slirp, odata, olen, &ri) < 0) {
return;
}
@@ -203,7 +203,6 @@ void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m)
dhcpv6_info_request(m->slirp, srcsas, xid, &data[4], data_len - 4);
break;
default:
- DEBUG_MISC((dfd, "dhcpv6_input: Unsupported message type 0x%x\n",
- data[0]));
+ DEBUG_MISC("dhcpv6_input: Unsupported message type 0x%x", data[0]);
}
}
diff --git a/slirp/if.c b/slirp/if.c
index 590753c658..73e3705740 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -131,12 +131,10 @@ diddit:
}
}
-#ifndef FULL_BOLT
/*
* This prevents us from malloc()ing too many mbufs
*/
if_start(ifm->slirp);
-#endif
}
/*
@@ -150,7 +148,7 @@ diddit:
*/
void if_start(Slirp *slirp)
{
- uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+ uint64_t now = slirp->cb->clock_get_ns();
bool from_batchq = false;
struct mbuf *ifm, *ifm_next, *ifqt;
diff --git a/slirp/ip.h b/slirp/ip.h
index 59cf4aa918..243b6c8b24 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -33,7 +33,9 @@
#ifndef IP_H
#define IP_H
-#ifdef HOST_WORDS_BIGENDIAN
+#include <glib.h>
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
# undef NTOHL
# undef NTOHS
# undef HTONL
@@ -69,7 +71,7 @@ typedef uint32_t n_long; /* long as received from the net */
* Structure of an internet header, naked of options.
*/
struct ip {
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t ip_v:4, /* version */
ip_hl:4; /* header length */
#else
@@ -135,7 +137,7 @@ struct ip_timestamp {
uint8_t ipt_code; /* IPOPT_TS */
uint8_t ipt_len; /* size of structure (variable) */
uint8_t ipt_ptr; /* index of current entry */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t ipt_oflw:4, /* overflow counter */
ipt_flg:4; /* flags, see below */
#else
@@ -175,7 +177,7 @@ struct ip_timestamp {
#define IP_MSS 576 /* default maximum segment size */
-#if SIZEOF_CHAR_P == 4
+#if GLIB_SIZEOF_VOID_P == 4
struct mbuf_ptr {
struct mbuf *mptr;
uint32_t dummy;
diff --git a/slirp/ip6.h b/slirp/ip6.h
index b1bea43b3c..14e9c78735 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -6,6 +6,7 @@
#ifndef SLIRP_IP6_H
#define SLIRP_IP6_H
+#include <glib.h>
#include "net/eth.h"
#define ALLNODES_MULTICAST { .s6_addr = \
@@ -113,7 +114,7 @@ static inline void in6_compute_ethaddr(struct in6_addr ip,
* Structure of an internet header, naked of options.
*/
struct ip6 {
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint32_t
ip_v:4, /* version */
ip_tc_hi:4, /* traffic class */
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index cd1e0b9fe1..5261baae27 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -17,7 +17,7 @@ static void ra_timer_handler(void *opaque)
{
Slirp *slirp = opaque;
timer_mod(slirp->ra_timer,
- qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
+ slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
ndp_send_ra(slirp);
}
@@ -31,7 +31,7 @@ void icmp6_init(Slirp *slirp)
SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
ra_timer_handler, slirp);
timer_mod(slirp->ra_timer,
- qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
+ slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
}
void icmp6_cleanup(Slirp *slirp)
@@ -74,9 +74,10 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
Slirp *slirp = m->slirp;
struct mbuf *t;
struct ip6 *ip = mtod(m, struct ip6 *);
+ char addrstr[INET6_ADDRSTRLEN];
DEBUG_CALL("icmp6_send_error");
- DEBUG_ARGS((dfd, " type = %d, code = %d\n", type, code));
+ DEBUG_ARG("type = %d, code = %d", type, code);
if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) ||
in6_zero(&ip->ip_src)) {
@@ -90,11 +91,8 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
struct ip6 *rip = mtod(t, struct ip6 *);
rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
rip->ip_dst = ip->ip_src;
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
- char addrstr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN);
DEBUG_ARG("target = %s", addrstr);
-#endif
rip->ip_nh = IPPROTO_ICMPV6;
const int error_data_len = MIN(m->m_len,
@@ -222,12 +220,12 @@ void ndp_send_ra(Slirp *slirp)
*/
void ndp_send_ns(Slirp *slirp, struct in6_addr addr)
{
- DEBUG_CALL("ndp_send_ns");
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
char addrstr[INET6_ADDRSTRLEN];
+
inet_ntop(AF_INET6, &addr, addrstr, INET6_ADDRSTRLEN);
+
+ DEBUG_CALL("ndp_send_ns");
DEBUG_ARG("target = %s", addrstr);
-#endif
/* Build IPv6 packet */
struct mbuf *t = m_get(slirp);
@@ -342,8 +340,7 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
case ICMP6_NDP_RA:
DEBUG_CALL(" type = Router Advertisement");
- qemu_log_mask(LOG_GUEST_ERROR,
- "Warning: guest sent NDP RA, but shouldn't");
+ slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't");
break;
case ICMP6_NDP_NS:
@@ -376,8 +373,8 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
case ICMP6_NDP_REDIRECT:
DEBUG_CALL(" type = Redirect");
- qemu_log_mask(LOG_GUEST_ERROR,
- "Warning: guest sent NDP REDIRECT, but shouldn't");
+ slirp->cb->guest_error(
+ "Warning: guest sent NDP REDIRECT, but shouldn't");
break;
}
}
@@ -393,7 +390,7 @@ void icmp6_input(struct mbuf *m)
int hlen = sizeof(struct ip6);
DEBUG_CALL("icmp6_input");
- DEBUG_ARG("m = %lx", (long) m);
+ DEBUG_ARG("m = %p", m);
DEBUG_ARG("m_len = %d", m->m_len);
if (ntohs(ip->ip_pl) < ICMP6_MINLEN) {
@@ -417,7 +414,7 @@ void icmp6_input(struct mbuf *m)
icmp6_send_echoreply(m, slirp, ip, icmp);
} else {
/* TODO */
- error_report("external icmpv6 not supported yet");
+ g_critical("external icmpv6 not supported yet");
}
break;
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index b3378b17b5..32b0914055 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -34,7 +34,7 @@ struct ndp_rs { /* Router Solicitation Message */
struct ndp_ra { /* Router Advertisement Message */
uint8_t chl; /* Cur Hop Limit */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t
M:1,
O:1,
@@ -56,7 +56,7 @@ struct ndp_ns { /* Neighbor Solicitation Message */
} QEMU_PACKED;
struct ndp_na { /* Neighbor Advertisement Message */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint32_t
R:1, /* Router Flag */
S:1, /* Solicited Flag */
@@ -125,7 +125,7 @@ struct ndpopt {
#define ndpopt_linklayer ndpopt_body.linklayer_addr
struct prefixinfo { /* Prefix Information */
uint8_t prefix_length;
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t L:1, A:1, reserved1:6;
#else
uint8_t reserved1:6, A:1, L:1;
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ac2e3ea882..ab656a0a9d 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -31,7 +31,7 @@ void ip6_input(struct mbuf *m)
}
DEBUG_CALL("ip6_input");
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("m = %p", m);
DEBUG_ARG("m_len = %d", m->m_len);
if (m->m_len < sizeof(struct ip6)) {
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 762cbfe89c..52c88ad691 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -19,8 +19,8 @@ int ip6_output(struct socket *so, struct mbuf *m, int fast)
struct ip6 *ip = mtod(m, struct ip6 *);
DEBUG_CALL("ip6_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("so = %p", so);
+ DEBUG_ARG("m = %p", m);
/* Fill IPv6 header */
ip->ip_v = IP6VERSION;
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 9210eef3f3..7c7e042049 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -34,6 +34,10 @@
#include "slirp.h"
#include "ip_icmp.h"
+#ifndef WITH_ICMP_ERROR_MSG
+#define WITH_ICMP_ERROR_MSG 0
+#endif
+
/* The message sent when emulating PING */
/* Be nice and tell them it's just a pseudo-ping packet */
static const char icmp_ping_msg[] = "This is a pseudo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
@@ -99,8 +103,8 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0,
(struct sockaddr *)&addr, sizeof(addr)) == -1) {
- DEBUG_MISC((dfd, "icmp_input icmp sendto tx errno = %d-%s\n",
- errno, strerror(errno)));
+ DEBUG_MISC("icmp_input icmp sendto tx errno = %d-%s",
+ errno, strerror(errno));
icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
icmp_detach(so);
}
@@ -165,8 +169,8 @@ icmp_input(struct mbuf *m, int hlen)
return;
}
if (udp_attach(so, AF_INET) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
- errno,strerror(errno)));
+ DEBUG_MISC("icmp_input udp_attach errno = %d-%s",
+ errno,strerror(errno));
sofree(so);
m_free(m);
goto end_error;
@@ -188,8 +192,8 @@ icmp_input(struct mbuf *m, int hlen)
if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
(struct sockaddr *)&addr, sockaddr_size(&addr)) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
- errno,strerror(errno)));
+ DEBUG_MISC("icmp_input udp sendto tx errno = %d-%s",
+ errno,strerror(errno));
icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
udp_detach(so);
}
@@ -253,13 +257,12 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
/* check msrc */
if(!msrc) goto end_error;
ip = mtod(msrc, struct ip *);
-#ifdef DEBUG
- { char bufa[20], bufb[20];
+ if (slirp_debug & DBG_MISC) {
+ char bufa[20], bufb[20];
strcpy(bufa, inet_ntoa(ip->ip_src));
strcpy(bufb, inet_ntoa(ip->ip_dst));
- DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb));
+ DEBUG_MISC(" %.16s to %.16s", bufa, bufb);
}
-#endif
if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */
/* Do not reply to source-only IPs */
@@ -319,8 +322,7 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
HTONS(icp->icmp_ip.ip_id);
HTONS(icp->icmp_ip.ip_off);
-#ifdef DEBUG
- if(message) { /* DEBUG : append message to ICMP packet */
+ if (message && WITH_ICMP_ERROR_MSG) { /* append message to ICMP packet */
int message_len;
char *cpnt;
message_len=strlen(message);
@@ -329,7 +331,6 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
memcpy(cpnt, message, message_len);
m->m_len+=message_len;
}
-#endif
icp->icmp_cksum = 0;
icp->icmp_cksum = cksum(m, m->m_len);
@@ -457,8 +458,8 @@ void icmp_receive(struct socket *so)
} else {
error_code = ICMP_UNREACH_HOST;
}
- DEBUG_MISC((dfd, " udp icmp rx errno = %d-%s\n", errno,
- strerror(errno)));
+ DEBUG_MISC(" udp icmp rx errno = %d-%s", errno,
+ strerror(errno));
icmp_send_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno));
} else {
icmp_reflect(so->so_m);
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 094a807d41..d360620838 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -448,206 +448,6 @@ ip_slowtimo(Slirp *slirp)
}
/*
- * Do option processing on a datagram,
- * possibly discarding it if bad options are encountered,
- * or forwarding it if source-routed.
- * Returns 1 if packet has been forwarded/freed,
- * 0 if the packet should be processed further.
- */
-
-#ifdef notdef
-
-int
-ip_dooptions(m)
- struct mbuf *m;
-{
- register struct ip *ip = mtod(m, struct ip *);
- register u_char *cp;
- register struct ip_timestamp *ipt;
- register struct in_ifaddr *ia;
- int opt, optlen, cnt, off, code, type, forward = 0;
- struct in_addr *sin, dst;
-typedef uint32_t n_time;
- n_time ntime;
-
- dst = ip->ip_dst;
- cp = (u_char *)(ip + 1);
- cnt = (ip->ip_hl << 2) - sizeof (struct ip);
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[IPOPT_OPTVAL];
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[IPOPT_OLEN];
- if (optlen <= 0 || optlen > cnt) {
- code = &cp[IPOPT_OLEN] - (u_char *)ip;
- goto bad;
- }
- }
- switch (opt) {
-
- default:
- break;
-
- /*
- * Source routing with record.
- * Find interface with current destination address.
- * If none on this machine then drop if strictly routed,
- * or do nothing if loosely routed.
- * Record interface address and bring up next address
- * component. If strictly routed make sure next
- * address is on directly accessible net.
- */
- case IPOPT_LSRR:
- case IPOPT_SSRR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- ipaddr.sin_addr = ip->ip_dst;
- ia = (struct in_ifaddr *)
- ifa_ifwithaddr((struct sockaddr *)&ipaddr);
- if (ia == 0) {
- if (opt == IPOPT_SSRR) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- /*
- * Loose routing, and not at next destination
- * yet; nothing to do except forward.
- */
- break;
- }
- off--; /* 0 origin */
- if (off > optlen - sizeof(struct in_addr)) {
- /*
- * End of source route. Should be for us.
- */
- save_rte(cp, ip->ip_src);
- break;
- }
- /*
- * locate outgoing interface
- */
- bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- if (opt == IPOPT_SSRR) {
-#define INA struct in_ifaddr *
-#define SA struct sockaddr *
- if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
- ia = (INA)ifa_ifwithnet((SA)&ipaddr);
- } else
- ia = ip_rtaddr(ipaddr.sin_addr);
- if (ia == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- ip->ip_dst = ipaddr.sin_addr;
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- /*
- * Let ip_intr's mcast routing check handle mcast pkts
- */
- forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));
- break;
-
- case IPOPT_RR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- /*
- * If no space remains, ignore.
- */
- off--; /* 0 origin */
- if (off > optlen - sizeof(struct in_addr))
- break;
- bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- /*
- * locate outgoing interface; if we're the destination,
- * use the incoming interface (should be same).
- */
- if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
- (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_HOST;
- goto bad;
- }
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS:
- code = cp - (u_char *)ip;
- ipt = (struct ip_timestamp *)cp;
- if (ipt->ipt_len < 5)
- goto bad;
- if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) {
- if (++ipt->ipt_oflw == 0)
- goto bad;
- break;
- }
- sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
- switch (ipt->ipt_flg) {
-
- case IPOPT_TS_TSONLY:
- break;
-
- case IPOPT_TS_TSANDADDR:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- ipaddr.sin_addr = dst;
- ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr,
- m->m_pkthdr.rcvif);
- if (ia == 0)
- continue;
- bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
- (caddr_t)sin, sizeof(struct in_addr));
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS_PRESPEC:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
- sizeof(struct in_addr));
- if (ifa_ifwithaddr((SA)&ipaddr) == 0)
- continue;
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- default:
- goto bad;
- }
- ntime = iptime();
- bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
- sizeof(n_time));
- ipt->ipt_ptr += sizeof(n_time);
- }
- }
- if (forward) {
- ip_forward(m, 1);
- return (1);
- }
- return (0);
-bad:
- icmp_send_error(m, type, code, 0, 0);
-
- return (1);
-}
-
-#endif /* notdef */
-
-/*
* Strip out IP options, at higher
* level protocol in the kernel.
* Second argument is buffer to which options
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 42e42e9a2a..4611a7447b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,8 +5,20 @@
typedef struct Slirp Slirp;
-int get_dns_addr(struct in_addr *pdns_addr);
-int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
+/*
+ * Callbacks from slirp
+ *
+ * The opaque parameter comes from the opaque parameter given to slirp_init().
+ */
+typedef struct SlirpCb {
+ /* Send an ethernet frame to the guest network. */
+ void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
+ /* Print a message for an error due to guest misbehavior. */
+ void (*guest_error)(const char *msg);
+ /* Return the virtual clock value in nanoseconds */
+ int64_t (*clock_get_ns)(void);
+} SlirpCb;
+
Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
struct in_addr vnetmask, struct in_addr vhost,
@@ -17,7 +29,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
- const char *vdomainname, void *opaque);
+ const char *vdomainname,
+ const SlirpCb *callbacks,
+ void *opaque);
void slirp_cleanup(Slirp *slirp);
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
@@ -26,18 +40,15 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error);
void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
-/* you must provide the following functions: */
-void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
-
int slirp_add_hostfwd(Slirp *slirp, int is_udp,
struct in_addr host_addr, int host_port,
struct in_addr guest_addr, int guest_port);
int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
+int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
struct in_addr *guest_addr, int guest_port);
-void slirp_connection_info(Slirp *slirp, Monitor *mon);
+char *slirp_connection_info(Slirp *slirp);
void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
int guest_port, const uint8_t *buf, int size);
diff --git a/slirp/main.h b/slirp/main.h
index 90053ce5ec..4bc05fb904 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -8,42 +8,9 @@
#ifndef SLIRP_MAIN_H
#define SLIRP_MAIN_H
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#define TOWRITEMAX 512
-
-extern int slirp_socket;
-extern int slirp_socket_unit;
-extern int slirp_socket_port;
-extern uint32_t slirp_socket_addr;
-extern char *slirp_socket_passwd;
-extern int ctty_closed;
-
-/*
- * Get the difference in 2 times from updtim()
- * Allow for wraparound times, "just in case"
- * x is the greater of the 2 (current time) and y is
- * what it's being compared against.
- */
-#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)
-
-extern char *slirp_tty;
-extern char *exec_shell;
extern u_int curtime;
extern struct in_addr loopback_addr;
extern unsigned long loopback_mask;
-extern char *username;
-extern char *socket_path;
-extern int towrite_max;
-extern int ppp_exit;
-extern int tcp_keepintvl;
-
-#define PROTO_SLIP 0x1
-#ifdef USE_PPP
-#define PROTO_PPP 0x2
-#endif
int if_encap(Slirp *slirp, struct mbuf *ifm);
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index aa1f28afb1..d8d275e0e7 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -232,7 +232,7 @@ dtom(Slirp *slirp, void *dat)
}
}
- DEBUG_ERROR((dfd, "dtom failed"));
+ DEBUG_ERROR("dtom failed");
return (struct mbuf *)0;
}
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index bfdf8c4577..cbf17e136b 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -72,7 +72,6 @@
* How much free room there is
*/
#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)
-#define M_TRAILINGSPACE M_FREEROOM
struct mbuf {
/* XXX should union some of these! */
diff --git a/slirp/misc.c b/slirp/misc.c
index 57bdd808e2..eae9596a55 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -8,14 +8,9 @@
#include "qemu/osdep.h"
#include "slirp.h"
#include "libslirp.h"
-#include "monitor/monitor.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#ifdef DEBUG
-int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
-#endif
-
inline void
insque(void *a, void *b)
{
@@ -37,189 +32,135 @@ remque(void *a)
element->qh_rlink = NULL;
}
-int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
+int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
struct in_addr addr, int port)
{
- struct ex_list *tmp_ptr;
-
- /* First, check if the port is "bound" */
- for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
- if (port == tmp_ptr->ex_fport &&
- addr.s_addr == tmp_ptr->ex_addr.s_addr)
- return -1;
- }
+ struct gfwd_list *tmp_ptr;
tmp_ptr = *ex_ptr;
- *ex_ptr = g_new(struct ex_list, 1);
+ *ex_ptr = g_new0(struct gfwd_list, 1);
(*ex_ptr)->ex_fport = port;
(*ex_ptr)->ex_addr = addr;
- (*ex_ptr)->ex_pty = do_pty;
- (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : g_strdup(exec);
+ if (chardev) {
+ (*ex_ptr)->ex_chardev = chardev;
+ } else {
+ (*ex_ptr)->ex_exec = g_strdup(cmdline);
+ }
(*ex_ptr)->ex_next = tmp_ptr;
return 0;
}
-#ifdef _WIN32
-
-int
-fork_exec(struct socket *so, const char *ex, int do_pty)
+static int
+slirp_socketpair_with_oob(int sv[2])
{
- /* not implemented */
- return 0;
-}
-
-#else
-
-/*
- * XXX This is ugly
- * We create and bind a socket, then fork off to another
- * process, which connects to this socket, after which we
- * exec the wanted program. If something (strange) happens,
- * the accept() call could block us forever.
- *
- * do_pty = 0 Fork/exec inetd style
- * do_pty = 1 Fork/exec using slirp.telnetd
- * do_ptr = 2 Fork/exec using pty
- */
-int
-fork_exec(struct socket *so, const char *ex, int do_pty)
-{
- int s, cs;
- struct sockaddr_in addr, csaddr;
- socklen_t addrlen = sizeof(addr);
- socklen_t csaddrlen = sizeof(csaddr);
- int opt;
- const char *argv[256];
- /* don't want to clobber the original */
- char *bptr;
- const char *curarg;
- int c, i, ret;
- pid_t pid;
-
- DEBUG_CALL("fork_exec");
- DEBUG_ARG("so = %p", so);
- DEBUG_ARG("ex = %p", ex);
- DEBUG_ARG("do_pty = %x", do_pty);
-
- if (do_pty == 2) {
- return 0;
- } else {
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = INADDR_ANY;
-
- if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
- bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
- listen(s, 1) < 0) {
- error_report("Error: inet socket: %s", strerror(errno));
- if (s >= 0) {
- closesocket(s);
- }
-
- return 0;
- }
- }
+ struct sockaddr_in addr = {
+ .sin_family = AF_INET,
+ .sin_port = 0,
+ .sin_addr.s_addr = INADDR_ANY,
+ };
+ socklen_t addrlen = sizeof(addr);
+ int ret, s;
+
+ sv[1] = -1;
+ s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
+ listen(s, 1) < 0 ||
+ getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
+ goto err;
+ }
- if (getsockname(s, (struct sockaddr *)&csaddr, &csaddrlen) < 0) {
- closesocket(s);
- return 0;
- }
- cs = qemu_socket(AF_INET, SOCK_STREAM, 0);
- if (cs < 0) {
- closesocket(s);
- return 0;
- }
- csaddr.sin_addr = loopback_addr;
- /*
- * This connect won't block because we've already listen()ed on
- * the server end (even though we won't accept() the connection
- * until later on).
- */
- do {
- ret = connect(cs, (struct sockaddr *)&csaddr, csaddrlen);
- } while (ret < 0 && errno == EINTR);
- if (ret < 0) {
- closesocket(s);
- closesocket(cs);
- return 0;
- }
+ sv[1] = qemu_socket(AF_INET, SOCK_STREAM, 0);
+ if (sv[1] < 0) {
+ goto err;
+ }
+ /*
+ * This connect won't block because we've already listen()ed on
+ * the server end (even though we won't accept() the connection
+ * until later on).
+ */
+ do {
+ ret = connect(sv[1], (struct sockaddr *)&addr, addrlen);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0) {
+ goto err;
+ }
- pid = fork();
- switch(pid) {
- case -1:
- error_report("Error: fork failed: %s", strerror(errno));
- closesocket(cs);
- close(s);
- return 0;
+ do {
+ sv[0] = accept(s, (struct sockaddr *)&addr, &addrlen);
+ } while (sv[0] < 0 && errno == EINTR);
+ if (sv[0] < 0) {
+ goto err;
+ }
- case 0:
- setsid();
+ closesocket(s);
+ return 0;
- /* Set the DISPLAY */
- close(s);
- dup2(cs, 0);
- dup2(cs, 1);
- dup2(cs, 2);
- for (s = getdtablesize() - 1; s >= 3; s--)
- close(s);
+err:
+ g_critical("slirp_socketpair(): %s", strerror(errno));
+ if (s >= 0) {
+ closesocket(s);
+ }
+ if (sv[1] >= 0) {
+ closesocket(sv[1]);
+ }
+ return -1;
+}
- i = 0;
- bptr = g_strdup(ex); /* No need to free() this */
- if (do_pty == 1) {
- /* Setup "slirp.telnetd -x" */
- argv[i++] = "slirp.telnetd";
- argv[i++] = "-x";
- argv[i++] = bptr;
- } else
- do {
- /* Change the string into argv[] */
- curarg = bptr;
- while (*bptr != ' ' && *bptr != (char)0)
- bptr++;
- c = *bptr;
- *bptr++ = (char)0;
- argv[i++] = g_strdup(curarg);
- } while (c);
+static void
+fork_exec_child_setup(gpointer data)
+{
+#ifndef _WIN32
+ setsid();
+#endif
+}
- argv[i] = NULL;
- execvp(argv[0], (char **)argv);
+int
+fork_exec(struct socket *so, const char *ex)
+{
+ GError *err = NULL;
+ char **argv;
+ int opt, sp[2];
- /* Ooops, failed, let's tell the user why */
- fprintf(stderr, "Error: execvp of %s failed: %s\n",
- argv[0], strerror(errno));
- close(0); close(1); close(2); /* XXX */
- exit(1);
+ DEBUG_CALL("fork_exec");
+ DEBUG_ARG("so = %p", so);
+ DEBUG_ARG("ex = %p", ex);
- default:
- qemu_add_child_watch(pid);
- closesocket(cs);
- /*
- * This should never block, because we already connect()ed
- * on the child end before we forked.
- */
- do {
- so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
- } while (so->s < 0 && errno == EINTR);
- closesocket(s);
- socket_set_fast_reuse(so->s);
- opt = 1;
- qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
- qemu_set_nonblock(so->s);
+ if (slirp_socketpair_with_oob(sp) < 0) {
+ return 0;
+ }
- /* Append the telnet options now */
- if (so->so_m != NULL && do_pty == 1) {
- sbappend(so, so->so_m);
- so->so_m = NULL;
- }
+ argv = g_strsplit(ex, " ", -1);
+ g_spawn_async_with_fds(NULL /* cwd */,
+ argv,
+ NULL /* env */,
+ G_SPAWN_SEARCH_PATH,
+ fork_exec_child_setup, NULL /* data */,
+ NULL /* child_pid */,
+ sp[1], sp[1], sp[1],
+ &err);
+ g_strfreev(argv);
+
+ if (err) {
+ g_critical("fork_exec: %s", err->message);
+ g_error_free(err);
+ closesocket(sp[0]);
+ closesocket(sp[1]);
+ return 0;
+ }
- return 1;
- }
+ so->s = sp[0];
+ closesocket(sp[1]);
+ socket_set_fast_reuse(so->s);
+ opt = 1;
+ qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ qemu_set_nonblock(so->s);
+ return 1;
}
-#endif
-void slirp_connection_info(Slirp *slirp, Monitor *mon)
+char *slirp_connection_info(Slirp *slirp)
{
+ GString *str = g_string_new(NULL);
const char * const tcpstates[] = {
[TCPS_CLOSED] = "CLOSED",
[TCPS_LISTEN] = "LISTEN",
@@ -241,8 +182,9 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
const char *state;
char buf[20];
- monitor_printf(mon, " Protocol[State] FD Source Address Port "
- "Dest. Address Port RecvQ SendQ\n");
+ g_string_append_printf(str,
+ " Protocol[State] FD Source Address Port "
+ "Dest. Address Port RecvQ SendQ\n");
for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
if (so->so_state & SS_HOSTFWD) {
@@ -264,10 +206,10 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
dst_port = so->so_fport;
}
snprintf(buf, sizeof(buf), " TCP[%s]", state);
- monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
ntohs(src.sin_port));
- monitor_printf(mon, "%15s %5d %5d %5d\n",
+ g_string_append_printf(str, "%15s %5d %5d %5d\n",
inet_ntoa(dst_addr), ntohs(dst_port),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
@@ -287,10 +229,10 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
dst_addr = so->so_faddr;
dst_port = so->so_fport;
}
- monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
ntohs(src.sin_port));
- monitor_printf(mon, "%15s %5d %5d %5d\n",
+ g_string_append_printf(str, "%15s %5d %5d %5d\n",
inet_ntoa(dst_addr), ntohs(dst_port),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
@@ -300,9 +242,11 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
(so->so_expire - curtime) / 1000);
src.sin_addr = so->so_laddr;
dst_addr = so->so_faddr;
- monitor_printf(mon, "%-19s %3d %15s - ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3d %15s - ", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
- monitor_printf(mon, "%15s - %5d %5d\n", inet_ntoa(dst_addr),
+ g_string_append_printf(str, "%15s - %5d %5d\n", inet_ntoa(dst_addr),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
+
+ return g_string_free(str, FALSE);
}
diff --git a/slirp/misc.h b/slirp/misc.h
index 5211bbd30a..1df707c052 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -8,12 +8,12 @@
#ifndef MISC_H
#define MISC_H
-struct ex_list {
- int ex_pty; /* Do we want a pty? */
+struct gfwd_list {
+ void *ex_chardev;
struct in_addr ex_addr; /* Server address */
int ex_fport; /* Port to telnet to */
- const char *ex_exec; /* Command line of what to exec */
- struct ex_list *ex_next;
+ char *ex_exec; /* Command line of what to exec */
+ struct gfwd_list *ex_next;
};
#define EMU_NONE 0x0
@@ -26,7 +26,6 @@ struct ex_list {
#define EMU_REALAUDIO 0x5
#define EMU_RLOGIN 0x6
#define EMU_IDENT 0x7
-#define EMU_RSH 0x8
#define EMU_NOCONNECT 0x10 /* Don't connect */
@@ -52,7 +51,7 @@ struct slirp_quehead {
void slirp_insque(void *, void *);
void slirp_remque(void *);
-int add_exec(struct ex_list **, int, char *, struct in_addr, int);
-int fork_exec(struct socket *so, const char *ex, int do_pty);
+int add_exec(struct gfwd_list **, void *, const char *, struct in_addr, int);
+int fork_exec(struct socket *so, const char *ex);
#endif
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 7116034afc..8594382270 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -128,7 +128,7 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
memset(reh->h_source, 0xff, ETH_ALEN);
reh->h_proto = htons(ETH_P_NCSI);
- for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
+ for (i = 0; i < G_N_ELEMENTS(ncsi_rsp_handlers); i++) {
if (ncsi_rsp_handlers[i].type == nh->type + 0x80) {
handler = &ncsi_rsp_handlers[i];
break;
@@ -163,5 +163,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
*pchecksum = htonl(checksum);
ncsi_rsp_len += 4;
- slirp_output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+ slirp->cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
}
diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
index e1676a0a7b..b7b73722f7 100644
--- a/slirp/ndp_table.c
+++ b/slirp/ndp_table.c
@@ -10,18 +10,17 @@
void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
uint8_t ethaddr[ETH_ALEN])
{
+ char addrstr[INET6_ADDRSTRLEN];
NdpTable *ndp_table = &slirp->ndp_table;
int i;
- DEBUG_CALL("ndp_table_add");
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
- char addrstr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
+
+ DEBUG_CALL("ndp_table_add");
DEBUG_ARG("ip = %s", addrstr);
-#endif
- DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
- ethaddr[0], ethaddr[1], ethaddr[2],
- ethaddr[3], ethaddr[4], ethaddr[5]));
+ DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+ ethaddr[0], ethaddr[1], ethaddr[2],
+ ethaddr[3], ethaddr[4], ethaddr[5]);
if (IN6_IS_ADDR_MULTICAST(&ip_addr) || in6_zero(&ip_addr)) {
/* Do not register multicast or unspecified addresses */
@@ -50,15 +49,14 @@ void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
uint8_t out_ethaddr[ETH_ALEN])
{
+ char addrstr[INET6_ADDRSTRLEN];
NdpTable *ndp_table = &slirp->ndp_table;
int i;
- DEBUG_CALL("ndp_table_search");
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
- char addrstr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
+
+ DEBUG_CALL("ndp_table_search");
DEBUG_ARG("ip = %s", addrstr);
-#endif
assert(!in6_zero(&ip_addr));
@@ -69,18 +67,18 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
out_ethaddr[3] = ip_addr.s6_addr[13];
out_ethaddr[4] = ip_addr.s6_addr[14];
out_ethaddr[5] = ip_addr.s6_addr[15];
- DEBUG_ARGS((dfd, " multicast addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
- out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
- out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+ DEBUG_ARG("multicast addr = %02x:%02x:%02x:%02x:%02x:%02x",
+ out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+ out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
return 1;
}
for (i = 0; i < NDP_TABLE_SIZE; i++) {
if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
memcpy(out_ethaddr, ndp_table->table[i].eth_addr, ETH_ALEN);
- DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
- out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
- out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+ DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+ out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+ out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
return 1;
}
}
diff --git a/slirp/sbuf.h b/slirp/sbuf.h
index a722ecb629..644c201341 100644
--- a/slirp/sbuf.h
+++ b/slirp/sbuf.h
@@ -8,7 +8,6 @@
#ifndef SBUF_H
#define SBUF_H
-#define sbflush(sb) sbdrop((sb),(sb)->sb_cc)
#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
struct sbuf {
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ab2fc4eb8b..a9674ab090 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -35,6 +35,11 @@
#include <net/if.h>
#endif
+int slirp_debug;
+
+/* Define to 1 if you want KEEPALIVE timers */
+bool slirp_do_keepalive;
+
/* host loopback address */
struct in_addr loopback_addr;
/* host loopback network mask */
@@ -161,9 +166,7 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
if (!f)
return -1;
-#ifdef DEBUG
- fprintf(stderr, "IP address of your DNS(s): ");
-#endif
+ DEBUG_MISC("IP address of your DNS(s):");
while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
char *c = strchr(buff2, '%');
@@ -186,26 +189,18 @@ static int get_dns_addr_resolv_conf(int af, void *pdns_addr, void *cached_addr,
}
*cached_time = curtime;
}
-#ifdef DEBUG
- else
- fprintf(stderr, ", ");
-#endif
+
if (++found > 3) {
-#ifdef DEBUG
- fprintf(stderr, "(more)");
-#endif
+ DEBUG_MISC(" (more)");
break;
- }
-#ifdef DEBUG
- else {
+ } else if (slirp_debug & DBG_MISC) {
char s[INET6_ADDRSTRLEN];
const char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
if (!res) {
- res = "(string conversion error)";
+ res = " (string conversion error)";
}
- fprintf(stderr, "%s", res);
+ DEBUG_MISC(" %s", res);
}
-#endif
}
}
fclose(f);
@@ -252,6 +247,7 @@ int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id)
static void slirp_init_once(void)
{
static int initialized;
+ const char *debug;
#ifdef _WIN32
WSADATA Data;
#endif
@@ -268,6 +264,18 @@ static void slirp_init_once(void)
loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
loopback_mask = htonl(IN_CLASSA_NET);
+
+ debug = g_getenv("SLIRP_DEBUG");
+ if (debug) {
+ const GDebugKey keys[] = {
+ { "call", DBG_CALL },
+ { "misc", DBG_MISC },
+ { "error", DBG_ERROR },
+ };
+ slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
+ }
+
+
}
static void slirp_state_save(QEMUFile *f, void *opaque);
@@ -287,12 +295,15 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
- const char *vdomainname, void *opaque)
+ const char *vdomainname,
+ const SlirpCb *callbacks,
+ void *opaque)
{
Slirp *slirp = g_malloc0(sizeof(Slirp));
slirp_init_once();
+ slirp->cb = callbacks;
slirp->grand = g_rand_new();
slirp->restricted = restricted;
@@ -339,6 +350,14 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
void slirp_cleanup(Slirp *slirp)
{
+ struct gfwd_list *e, *next;
+
+ for (e = slirp->guestfwd_list; e; e = next) {
+ next = e->ex_next;
+ g_free(e->ex_exec);
+ g_free(e);
+ }
+
QTAILQ_REMOVE(&slirp_instances, slirp, entry);
unregister_savevm(NULL, "slirp", slirp);
@@ -560,15 +579,15 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
void slirp_pollfds_poll(GArray *pollfds, int select_error)
{
- Slirp *slirp;
+ Slirp *slirp = QTAILQ_FIRST(&slirp_instances);
struct socket *so, *so_next;
int ret;
- if (QTAILQ_EMPTY(&slirp_instances)) {
+ if (!slirp) {
return;
}
- curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ curtime = slirp->cb->clock_get_ns() / SCALE_MS;
QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
@@ -688,47 +707,6 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
}
}
}
-
- /*
- * Probe a still-connecting, non-blocking socket
- * to check if it's still alive
- */
-#ifdef PROBE_CONN
- if (so->so_state & SS_ISFCONNECTING) {
- ret = qemu_recv(so->s, &ret, 0, 0);
-
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN) {
- continue; /* Still connecting, continue */
- }
-
- /* else failed */
- so->so_state &= SS_PERSISTENT_MASK;
- so->so_state |= SS_NOFDREF;
-
- /* tcp_input will take care of it */
- } else {
- ret = send(so->s, &ret, 0, 0);
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN) {
- continue;
- }
- /* else failed */
- so->so_state &= SS_PERSISTENT_MASK;
- so->so_state |= SS_NOFDREF;
- } else {
- so->so_state &= ~SS_ISFCONNECTING;
- }
-
- }
- tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
- so->so_ffamily);
- } /* SS_ISFCONNECTING */
-#endif
}
/*
@@ -787,7 +765,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
struct ethhdr *reh = (struct ethhdr *)arp_reply;
struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN);
int ar_op;
- struct ex_list *ex_ptr;
+ struct gfwd_list *ex_ptr;
if (!slirp->in_enabled) {
return;
@@ -807,7 +785,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
ah->ar_tip == slirp->vhost_addr.s_addr)
goto arp_ok;
- for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
goto arp_ok;
}
@@ -832,7 +810,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
rah->ar_sip = ah->ar_tip;
memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
rah->ar_tip = ah->ar_sip;
- slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
+ slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
}
break;
case ARPOP_REPLY:
@@ -932,11 +910,11 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
/* target IP */
rah->ar_tip = iph->ip_dst.s_addr;
slirp->client_ipaddr = iph->ip_dst;
- slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
+ slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
ifm->resolution_requested = true;
/* Expire request and drop outgoing packet after 1 second */
- ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
+ ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
}
return 0;
} else {
@@ -962,8 +940,7 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
if (!ifm->resolution_requested) {
ndp_send_ns(slirp, ip6h->ip_dst);
ifm->resolution_requested = true;
- ifm->expiration_date =
- qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
+ ifm->expiration_date = slirp->cb->clock_get_ns() + 1000000000ULL;
}
return 0;
} else {
@@ -1011,14 +988,14 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
}
memcpy(eh->h_dest, ethaddr, ETH_ALEN);
- DEBUG_ARGS((dfd, " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
- eh->h_source[0], eh->h_source[1], eh->h_source[2],
- eh->h_source[3], eh->h_source[4], eh->h_source[5]));
- DEBUG_ARGS((dfd, " dst = %02x:%02x:%02x:%02x:%02x:%02x\n",
- eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
- eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
+ DEBUG_ARG("src = %02x:%02x:%02x:%02x:%02x:%02x",
+ eh->h_source[0], eh->h_source[1], eh->h_source[2],
+ eh->h_source[3], eh->h_source[4], eh->h_source[5]);
+ DEBUG_ARG("dst = %02x:%02x:%02x:%02x:%02x:%02x",
+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
- slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+ slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
return 1;
}
@@ -1065,9 +1042,11 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
return 0;
}
-int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
- struct in_addr *guest_addr, int guest_port)
+static bool
+check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
{
+ struct gfwd_list *tmp_ptr;
+
if (!guest_addr->s_addr) {
guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
(htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
@@ -1076,18 +1055,36 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
slirp->vnetwork_addr.s_addr ||
guest_addr->s_addr == slirp->vhost_addr.s_addr ||
guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
+ return false;
+ }
+
+ /* check if the port is "bound" */
+ for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
+ if (guest_port == tmp_ptr->ex_fport &&
+ guest_addr->s_addr == tmp_ptr->ex_addr.s_addr)
+ return false;
+ }
+
+ return true;
+}
+
+int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+ struct in_addr *guest_addr, int guest_port)
+{
+ if (!check_guestfwd(slirp, guest_addr, guest_port)) {
return -1;
}
- return add_exec(&slirp->exec_list, do_pty, (char *)args, *guest_addr,
+
+ return add_exec(&slirp->guestfwd_list, chardev, cmdline, *guest_addr,
htons(guest_port));
}
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
{
- if (so->s == -1 && so->extra) {
+ if (so->s == -1 && so->chardev) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(so->extra, buf, len);
+ qemu_chr_fe_write_all(so->chardev, buf, len);
return len;
}
@@ -1240,8 +1237,8 @@ static int sbuf_tmp_post_load(void *opaque, int version)
}
if (tmp->woff >= requested_len ||
tmp->roff >= requested_len) {
- error_report("invalid sbuf offsets r/w=%u/%u len=%u",
- tmp->roff, tmp->woff, requested_len);
+ g_critical("invalid sbuf offsets r/w=%u/%u len=%u",
+ tmp->roff, tmp->woff, requested_len);
return -EINVAL;
}
@@ -1349,7 +1346,7 @@ static int ss_family_post_load(void *opaque, int version_id)
tss->parent->ss.ss_family = AF_INET6;
break;
default:
- error_report("invalid ss_family type %x", tss->portable_family);
+ g_critical("invalid ss_family type %x", tss->portable_family);
return -EINVAL;
}
@@ -1449,10 +1446,10 @@ static const VMStateDescription vmstate_slirp = {
static void slirp_state_save(QEMUFile *f, void *opaque)
{
Slirp *slirp = opaque;
- struct ex_list *ex_ptr;
+ struct gfwd_list *ex_ptr;
- for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
- if (ex_ptr->ex_pty == 3) {
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+ if (ex_ptr->ex_chardev) {
struct socket *so;
so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
ntohs(ex_ptr->ex_fport));
@@ -1471,7 +1468,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
{
Slirp *slirp = opaque;
- struct ex_list *ex_ptr;
+ struct gfwd_list *ex_ptr;
while (qemu_get_byte(f)) {
int ret;
@@ -1486,8 +1483,8 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
slirp->vnetwork_addr.s_addr) {
return -EINVAL;
}
- for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
- if (ex_ptr->ex_pty == 3 &&
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ if (ex_ptr->ex_chardev &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
so->so_fport == ex_ptr->ex_fport) {
break;
@@ -1495,8 +1492,6 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
}
if (!ex_ptr)
return -EINVAL;
-
- so->extra = (void *)ex_ptr->ex_exec;
}
return vmstate_load_state(f, &vmstate_slirp, slirp, version_id);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index b80725a0d6..9aa245715d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -1,8 +1,6 @@
#ifndef SLIRP_H
#define SLIRP_H
-#include "slirp_config.h"
-
#ifdef _WIN32
typedef char *caddr_t;
@@ -19,10 +17,6 @@ typedef char *caddr_t;
# endif
#endif
-#ifdef HAVE_SYS_BITYPES_H
-# include <sys/bitypes.h>
-#endif
-
#ifndef _WIN32
#include <sys/uio.h>
#endif
@@ -32,29 +26,15 @@ typedef char *caddr_t;
#include <arpa/inet.h>
#endif
-#ifndef NO_UNIX_SOCKETS
-#include <sys/un.h>
-#endif
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif
#ifndef _WIN32
#include <sys/socket.h>
#endif
-#if defined(HAVE_SYS_IOCTL_H)
+#ifndef _WIN32
# include <sys/ioctl.h>
#endif
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
+#ifdef __APPLE__
# include <sys/filio.h>
#endif
@@ -64,11 +44,6 @@ typedef char *caddr_t;
#define remque slirp_remque
#define quehead slirp_quehead
-#ifdef HAVE_SYS_STROPTS_H
-#include <sys/stropts.h>
-#endif
-
-
#include "debug.h"
#include "qemu/queue.h"
@@ -172,7 +147,7 @@ struct Slirp {
char client_hostname[33];
int restricted;
- struct ex_list *exec_list;
+ struct gfwd_list *guestfwd_list;
/* mbuf states */
struct quehead m_freelist;
@@ -220,17 +195,15 @@ struct Slirp {
GRand *grand;
QEMUTimer *ra_timer;
+ const SlirpCb *cb;
void *opaque;
};
-extern Slirp *slirp_instance;
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
void if_start(Slirp *);
+int get_dns_addr(struct in_addr *pdns_addr);
+int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
+
/* ncsi.c */
void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
@@ -238,7 +211,9 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
#include <netdb.h>
#endif
-#define SO_OPTIONS DO_KEEPALIVE
+
+extern bool slirp_do_keepalive;
+
#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
/* dnssearch.c */
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
deleted file mode 100644
index c59f655207..0000000000
--- a/slirp/slirp_config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * User definable configuration options
- */
-
-/* Define if you want the connection to be probed */
-/* XXX Not working yet, so ignore this for now */
-#undef PROBE_CONN
-
-/* Define to 1 if you want KEEPALIVE timers */
-#define DO_KEEPALIVE 0
-
-/* Define this if you want slirp to write to the tty as fast as it can */
-/* This should only be set if you are using load-balancing, slirp does a */
-/* pretty good job on single modems already, and seting this will make */
-/* interactive sessions less responsive */
-/* XXXXX Talk about having fast modem as unit 0 */
-#undef FULL_BOLT
-
-/*********************************************************/
-/*
- * Autoconf defined configuration options
- * You shouldn't need to touch any of these
- */
-
-/* Define if you have sys/ioctl.h */
-#undef HAVE_SYS_IOCTL_H
-#ifndef _WIN32
-#define HAVE_SYS_IOCTL_H
-#endif
-
-/* Define if you have sys/filio.h */
-#undef HAVE_SYS_FILIO_H
-#ifdef __APPLE__
-#define HAVE_SYS_FILIO_H
-#endif
-
-/* Define if you have sys/bitypes.h */
-#undef HAVE_SYS_BITYPES_H
-
-/* Define if the machine is big endian */
-//#undef HOST_WORDS_BIGENDIAN
-
-/* Define if you have readv */
-#undef HAVE_READV
-
-/* Define if iovec needs to be declared */
-#undef DECLARE_IOVEC
-#ifdef _WIN32
-#define DECLARE_IOVEC
-#endif
-
-/* Define if you have a POSIX.1 sys/wait.h */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have sys/select.h */
-#undef HAVE_SYS_SELECT_H
-#ifndef _WIN32
-#define HAVE_SYS_SELECT_H
-#endif
-
-/* Define if you have arpa/inet.h */
-#undef HAVE_ARPA_INET_H
-#ifndef _WIN32
-#define HAVE_ARPA_INET_H
-#endif
-
-/* Define if you have sys/signal.h */
-#undef HAVE_SYS_SIGNAL_H
-
-/* Define if you have sys/stropts.h */
-#undef HAVE_SYS_STROPTS_H
-
-/* Define to sizeof(char *) */
-#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
-
-/* Define if you have inet_aton */
-#undef HAVE_INET_ATON
-#ifndef _WIN32
-#define HAVE_INET_ATON
-#endif
-
-/* Define if you DON'T have unix-domain sockets */
-#undef NO_UNIX_SOCKETS
-#ifdef _WIN32
-#define NO_UNIX_SOCKETS
-#endif
diff --git a/slirp/socket.c b/slirp/socket.c
index c01d8696af..5ffbaa064a 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -89,10 +89,6 @@ sofree(struct socket *so)
soqfree(so, &slirp->if_fastq);
soqfree(so, &slirp->if_batchq);
- if (so->so_emu==EMU_RSH && so->extra) {
- sofree(so->extra);
- so->extra=NULL;
- }
if (so == slirp->tcp_last_so) {
slirp->tcp_last_so = &slirp->tcb;
} else if (so == slirp->udp_last_so) {
@@ -191,12 +187,7 @@ soread(struct socket *so)
*/
sopreprbuf(so, iov, &n);
-#ifdef HAVE_READV
- nn = readv(so->s, (struct iovec *)iov, n);
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#else
nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
-#endif
if (nn <= 0) {
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
return 0;
@@ -217,7 +208,8 @@ soread(struct socket *so)
}
}
- DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
+ DEBUG_MISC(" --- soread() disconnected, nn = %d, errno = %d-%s",
+ nn, errno,strerror(errno));
sofcantrcvmore(so);
if (err == ECONNRESET || err == ECONNREFUSED
@@ -230,7 +222,6 @@ soread(struct socket *so)
}
}
-#ifndef HAVE_READV
/*
* If there was no error, try and read the second time round
* We read again if n = 2 (ie, there's another part of the buffer)
@@ -247,8 +238,7 @@ soread(struct socket *so)
nn += ret;
}
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#endif
+ DEBUG_MISC(" ... read nn = %d bytes", nn);
/* Update fields */
sb->sb_cc += nn;
@@ -296,7 +286,7 @@ err:
sofcantrcvmore(so);
tcp_sockclosed(sototcpcb(so));
- fprintf(stderr, "soreadbuf buffer to small");
+ g_critical("soreadbuf buffer too small");
return -1;
}
@@ -381,7 +371,7 @@ sosendoob(struct socket *so)
n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
#ifdef DEBUG
if (n != len) {
- DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
+ DEBUG_ERROR("Didn't send all data urgently XXXXX");
}
#endif
}
@@ -390,7 +380,7 @@ sosendoob(struct socket *so)
return n;
}
so->so_urgc -= n;
- DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
+ DEBUG_MISC(" ---2 sent %d bytes urgent data, %d urgent bytes left", n, so->so_urgc);
sb->sb_cc -= n;
sb->sb_rptr += n;
@@ -456,13 +446,7 @@ sowrite(struct socket *so)
}
/* Check if there's urgent data to send, and if so, send it */
-#ifdef HAVE_READV
- nn = writev(so->s, (const struct iovec *)iov, n);
-
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#else
nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
-#endif
/* This should never happen, but people tell me it does *shrug* */
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
return 0;
@@ -471,15 +455,13 @@ sowrite(struct socket *so)
goto err_disconnected;
}
-#ifndef HAVE_READV
if (n == 2 && nn == iov[0].iov_len) {
int ret;
ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
if (ret > 0)
nn += ret;
}
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#endif
+ DEBUG_MISC(" ... wrote nn = %d bytes", nn);
/* Update sbuf */
sb->sb_cc -= nn;
@@ -497,8 +479,8 @@ sowrite(struct socket *so)
return nn;
err_disconnected:
- DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
- so->so_state, errno));
+ DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d",
+ so->so_state, errno);
sofcantsendmore(so);
tcp_sockclosed(sototcpcb(so));
return -1;
@@ -531,8 +513,8 @@ sorecvfrom(struct socket *so)
if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
- DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
- errno,strerror(errno)));
+ DEBUG_MISC(" udp icmp rx errno = %d-%s",
+ errno,strerror(errno));
icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
} else {
icmp_reflect(so->so_m);
@@ -583,8 +565,8 @@ sorecvfrom(struct socket *so)
m->m_len = recvfrom(so->s, m->m_data, len, 0,
(struct sockaddr *)&addr, &addrlen);
- DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
- m->m_len, errno,strerror(errno)));
+ DEBUG_MISC(" did recvfrom %d, errno = %d-%s",
+ m->m_len, errno,strerror(errno));
if(m->m_len<0) {
/* Report error as ICMP */
switch (so->so_lfamily) {
@@ -598,7 +580,7 @@ sorecvfrom(struct socket *so)
code = ICMP_UNREACH_NET;
}
- DEBUG_MISC((dfd, " rx error, tx icmp ICMP_UNREACH:%i\n", code));
+ DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
break;
case AF_INET6:
@@ -610,7 +592,7 @@ sorecvfrom(struct socket *so)
code = ICMP6_UNREACH_NO_ROUTE;
}
- DEBUG_MISC((dfd, " rx error, tx icmp6 ICMP_UNREACH:%i\n", code));
+ DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
break;
default:
@@ -858,9 +840,8 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
}
}
- DEBUG_MISC((dfd, " addr.sin_port=%d, "
- "addr.sin_addr.s_addr=%.16s\n",
- ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
+ DEBUG_MISC(" addr.sin_port=%d, addr.sin_addr.s_addr=%.16s",
+ ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
break;
case AF_INET6:
diff --git a/slirp/socket.h b/slirp/socket.h
index 2f224bc34f..930ed95972 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -67,7 +67,7 @@ struct socket {
struct sbuf so_rcv; /* Receive buffer */
struct sbuf so_snd; /* Send buffer */
- void * extra; /* Extra pointer */
+ void * chardev;
};
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 174d3d960c..47aaea6c5b 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -33,6 +33,8 @@
#ifndef TCP_H
#define TCP_H
+#include <glib.h>
+
typedef uint32_t tcp_seq;
#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */
@@ -51,7 +53,7 @@ struct tcphdr {
uint16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t th_off:4, /* data offset */
th_x2:4; /* (unused) */
#else
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 09bdf9b482..de5b74a52b 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -60,27 +60,6 @@
* Set DELACK for segments received in order, but ack immediately
* when segments are out of order (so fast retransmit can work).
*/
-#ifdef TCP_ACK_HACK
-#define TCP_REASS(tp, ti, m, so, flags) {\
- if ((ti)->ti_seq == (tp)->rcv_nxt && \
- tcpfrag_list_empty(tp) && \
- (tp)->t_state == TCPS_ESTABLISHED) {\
- if (ti->ti_flags & TH_PUSH) \
- tp->t_flags |= TF_ACKNOW; \
- else \
- tp->t_flags |= TF_DELACK; \
- (tp)->rcv_nxt += (ti)->ti_len; \
- flags = (ti)->ti_flags & TH_FIN; \
- if (so->so_emu) { \
- if (tcp_emu((so),(m))) sbappend((so), (m)); \
- } else \
- sbappend((so), (m)); \
- } else {\
- (flags) = tcp_reass((tp), (ti), (m)); \
- tp->t_flags |= TF_ACKNOW; \
- } \
-}
-#else
#define TCP_REASS(tp, ti, m, so, flags) { \
if ((ti)->ti_seq == (tp)->rcv_nxt && \
tcpfrag_list_empty(tp) && \
@@ -97,7 +76,7 @@
tp->t_flags |= TF_ACKNOW; \
} \
}
-#endif
+
static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
struct tcpiphdr *ti);
static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);
@@ -232,12 +211,12 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
struct sockaddr_storage lhost, fhost;
struct sockaddr_in *lhost4, *fhost4;
struct sockaddr_in6 *lhost6, *fhost6;
- struct ex_list *ex_ptr;
+ struct gfwd_list *ex_ptr;
Slirp *slirp;
DEBUG_CALL("tcp_input");
- DEBUG_ARGS((dfd, " m = %p iphlen = %2d inso = %p\n",
- m, iphlen, inso));
+ DEBUG_ARG("m = %p iphlen = %2d inso = %p",
+ m, iphlen, inso);
/*
* If called with m == 0, then we're continuing the connect
@@ -415,7 +394,7 @@ findso:
* for non-hostfwd connections. These should be dropped, unless it
* happens to be a guestfwd.
*/
- for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == ti->ti_dport &&
ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
break;
@@ -481,7 +460,7 @@ findso:
* Reset idle time and keep-alive timer.
*/
tp->t_idle = 0;
- if (SO_OPTIONS)
+ if (slirp_do_keepalive)
tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
else
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
@@ -637,7 +616,7 @@ findso:
if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
/* May be an add exec */
- for (ex_ptr = slirp->exec_list; ex_ptr;
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr;
ex_ptr = ex_ptr->ex_next) {
if(ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
@@ -662,8 +641,7 @@ findso:
(errno != EINPROGRESS) && (errno != EWOULDBLOCK)
) {
uint8_t code;
- DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n",
- errno,strerror(errno)));
+ DEBUG_MISC(" tcp fconnect errno = %d-%s", errno, strerror(errno));
if(errno == ECONNREFUSED) {
/* ACK the SYN, send RST to refuse the connection */
tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq) 0,
@@ -1032,8 +1010,7 @@ trimthenstep6:
if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
- DEBUG_MISC((dfd, " dup ack m = %p so = %p\n",
- m, so));
+ DEBUG_MISC(" dup ack m = %p so = %p", m, so);
/*
* If we have outstanding data (other than
* a window probe), this is a completely
@@ -1411,7 +1388,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
int opt, optlen;
DEBUG_CALL("tcp_dooptions");
- DEBUG_ARGS((dfd, " tp = %p cnt=%i\n", tp, cnt));
+ DEBUG_ARG("tp = %p cnt=%i", tp, cnt);
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[0];
@@ -1442,45 +1419,6 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
}
}
-
-/*
- * Pull out of band byte out of a segment so
- * it doesn't appear in the user's data queue.
- * It is still reflected in the segment length for
- * sequencing purposes.
- */
-
-#ifdef notdef
-
-void
-tcp_pulloutofband(so, ti, m)
- struct socket *so;
- struct tcpiphdr *ti;
- register struct mbuf *m;
-{
- int cnt = ti->ti_urp - 1;
-
- while (cnt >= 0) {
- if (m->m_len > cnt) {
- char *cp = mtod(m, caddr_t) + cnt;
- struct tcpcb *tp = sototcpcb(so);
-
- tp->t_iobc = *cp;
- tp->t_oobflags |= TCPOOB_HAVEDATA;
- memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1));
- m->m_len--;
- return;
- }
- cnt -= m->m_len;
- m = m->m_next; /* XXX WRONG! Fix it! */
- if (m == 0)
- break;
- }
- panic("tcp_pulloutofband");
-}
-
-#endif /* notdef */
-
/*
* Collect new round-trip time estimate
* and update averages and current timeout.
@@ -1611,7 +1549,7 @@ tcp_mss(struct tcpcb *tp, u_int offer)
(mss - (TCP_RCVSPACE % mss)) :
0));
- DEBUG_MISC((dfd, " returning mss = %d\n", mss));
+ DEBUG_MISC(" returning mss = %d", mss);
return mss;
}
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index c835432812..6dd1ecf5d9 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -92,7 +92,7 @@ again:
flags = tcp_outflags[tp->t_state];
- DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
+ DEBUG_MISC(" --- tcp_output flags = 0x%x", flags);
/*
* If in persist timeout with window of 0, send 1 byte.
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index fa61349cbb..23a841f26e 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -420,7 +420,7 @@ int tcp_fconnect(struct socket *so, unsigned short af)
qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
addr = so->fhost.ss;
- DEBUG_CALL(" connect()ing")
+ DEBUG_CALL(" connect()ing");
sotranslate_out(so, &addr);
/* We don't care what port we get */
@@ -541,7 +541,6 @@ static const struct tos_t tcptos[] = {
{0, 23, IPTOS_LOWDELAY, 0}, /* telnet */
{0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */
{0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */
- {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */
{0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */
{0, 543, IPTOS_LOWDELAY, 0}, /* klogin */
{0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */
@@ -635,6 +634,11 @@ tcp_emu(struct socket *so, struct mbuf *m)
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
+ if (m->m_len > so_rcv->sb_datalen
+ - (so_rcv->sb_wptr - so_rcv->sb_data)) {
+ return 1;
+ }
+
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
@@ -950,25 +954,23 @@ int tcp_ctl(struct socket *so)
{
Slirp *slirp = so->slirp;
struct sbuf *sb = &so->so_snd;
- struct ex_list *ex_ptr;
- int do_pty;
+ struct gfwd_list *ex_ptr;
DEBUG_CALL("tcp_ctl");
DEBUG_ARG("so = %p", so);
if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
/* Check if it's pty_exec */
- for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+ for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
- if (ex_ptr->ex_pty == 3) {
+ if (ex_ptr->ex_chardev) {
so->s = -1;
- so->extra = (void *)ex_ptr->ex_exec;
+ so->chardev = ex_ptr->ex_chardev;
return 1;
}
- do_pty = ex_ptr->ex_pty;
- DEBUG_MISC((dfd, " executing %s\n", ex_ptr->ex_exec));
- return fork_exec(so, ex_ptr->ex_exec, do_pty);
+ DEBUG_MISC(" executing %s", ex_ptr->ex_exec);
+ return fork_exec(so, ex_ptr->ex_exec);
}
}
}
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index dc8288b511..a843e57a2b 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -262,7 +262,7 @@ tcp_timers(register struct tcpcb *tp, int timer)
if (tp->t_state < TCPS_ESTABLISHED)
goto dropit;
- if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) {
+ if (slirp_do_keepalive && tp->t_state <= TCPS_CLOSE_WAIT) {
if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE)
goto dropit;
/*
diff --git a/slirp/tftp.c b/slirp/tftp.c
index a9bc4bb1b6..a9ba1480db 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -26,6 +26,7 @@
#include "slirp.h"
#include "qemu-common.h"
#include "qemu/cutils.h"
+#include "trace.h"
static inline int tftp_session_in_use(struct tftp_session *spt)
{
@@ -204,6 +205,7 @@ static void tftp_send_error(struct tftp_session *spt,
struct mbuf *m;
struct tftp_t *tp;
+ trace_slirp_tftp_error(msg);
m = m_get(spt->slirp);
if (!m) {
@@ -323,6 +325,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
break;
}
}
+ trace_slirp_tftp_rrq(req_fname);
/* check mode */
if ((pktlen - k) < 6) {
@@ -356,7 +359,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
return;
}
- while (k < pktlen && nb_options < ARRAY_SIZE(option_name)) {
+ while (k < pktlen && nb_options < G_N_ELEMENTS(option_name)) {
const char *key, *value;
key = &tp->x.tp_buf[k];
@@ -400,7 +403,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
}
if (nb_options > 0) {
- assert(nb_options <= ARRAY_SIZE(option_name));
+ assert(nb_options <= G_N_ELEMENTS(option_name));
tftp_send_oack(spt, option_name, option_value, nb_options, tp);
return;
}
diff --git a/slirp/trace-events b/slirp/trace-events
new file mode 100644
index 0000000000..ff8f656e8c
--- /dev/null
+++ b/slirp/trace-events
@@ -0,0 +1,5 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# slirp/tftp.c
+slirp_tftp_rrq(const char *file) "file: %s"
+slirp_tftp_error(const char *file) "msg: %s"
diff --git a/slirp/udp.c b/slirp/udp.c
index 5bb196c907..309feb9aae 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -172,8 +172,7 @@ udp_input(register struct mbuf *m, int iphlen)
*/
so = socreate(slirp);
if (udp_attach(so, AF_INET) == -1) {
- DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
- errno,strerror(errno)));
+ DEBUG_MISC(" udp_attach errno = %d-%s", errno, strerror(errno));
sofree(so);
goto bad;
}
@@ -209,7 +208,7 @@ udp_input(register struct mbuf *m, int iphlen)
m->m_len += iphlen;
m->m_data -= iphlen;
*ip=save_ip;
- DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
+ DEBUG_MISC("udp tx errno = %d-%s", errno, strerror(errno));
icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0,
strerror(errno));
goto bad;
diff --git a/slirp/udp6.c b/slirp/udp6.c
index 986010f0d3..fa531e03c4 100644
--- a/slirp/udp6.c
+++ b/slirp/udp6.c
@@ -20,7 +20,7 @@ void udp6_input(struct mbuf *m)
struct sockaddr_in6 lhost;
DEBUG_CALL("udp6_input");
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("m = %p", m);
if (slirp->restricted) {
goto bad;
@@ -92,8 +92,7 @@ void udp6_input(struct mbuf *m)
/* If there's no socket for this packet, create one. */
so = socreate(slirp);
if (udp_attach(so, AF_INET6) == -1) {
- DEBUG_MISC((dfd, " udp6_attach errno = %d-%s\n",
- errno, strerror(errno)));
+ DEBUG_MISC(" udp6_attach errno = %d-%s", errno, strerror(errno));
sofree(so);
goto bad;
}
@@ -119,7 +118,7 @@ void udp6_input(struct mbuf *m)
m->m_len += iphlen;
m->m_data -= iphlen;
*ip = save_ip;
- DEBUG_MISC((dfd, "udp tx errno = %d-%s\n", errno, strerror(errno)));
+ DEBUG_MISC("udp tx errno = %d-%s", errno, strerror(errno));
icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
goto bad;
}
@@ -144,8 +143,8 @@ int udp6_output(struct socket *so, struct mbuf *m,
struct udphdr *uh;
DEBUG_CALL("udp6_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("so = %p", so);
+ DEBUG_ARG("m = %p", m);
/* adjust for header */
m->m_data -= sizeof(struct udphdr);
diff --git a/stubs/slirp.c b/stubs/slirp.c
index 42f7e1afd0..70704346fd 100644
--- a/stubs/slirp.c
+++ b/stubs/slirp.c
@@ -1,7 +1,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/host-utils.h"
-#include "slirp/slirp.h"
+#include "slirp/libslirp.h"
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
{