Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging

slirp updates

Gerd Hoffmann (1):
  slirp: add tftp tracing

Marc-André Lureau (61):
  slirp: associate slirp_output callback with the Slirp context
  slirp: remove do_pty from fork_exec()
  slirp: replace ex_pty with ex_chardev
  slirp: use a dedicated field for chardev pointer
  slirp: remove unused EMU_RSH
  slirp: rename /extra/chardev
  slirp: move internal function declarations
  slirp: remove Monitor dependency, return a string for info
  slirp: fix slirp_add_exec() leaks
  slirp: replace the poor-man string split with g_strsplit()
  slirp: remove dead declarations
  slirp: move socket pair creation in helper function
  slirp: remove unused M_TRAILINGSPACE
  slirp: use a callback structure to interface with qemu
  slirp: remove PROBE_CONN dead-code
  slirp: remove FULL_BOLT
  slirp: remove the disabled readv()/writev() code path
  slirp: remove HAVE_SYS_SIGNAL_H
  slirp: remove unused HAVE_SYS_BITYPES_H
  slirp: remove NO_UNIX_SOCKETS
  slirp: remove unused HAVE_SYS_STROPTS_H
  slirp: remove unused HAVE_ARPA_INET_H
  slirp: remove unused HAVE_SYS_WAIT_H
  slirp: remove unused HAVE_SYS_SELECT_H
  slirp: remove HAVE_SYS_IOCTL_H
  slirp: remove HAVE_SYS_FILIO_H
  slirp: remove unused DECLARE_IOVEC
  slirp: remove unused HAVE_INET_ATON
  slirp: replace HOST_WORDS_BIGENDIAN with glib equivalent
  slirp: replace SIZEOF_CHAR_P with glib equivalent
  slirp: replace compile time DO_KEEPALIVE
  slirp: remove unused global slirp_instance
  slirp: replace error_report() with g_critical()
  slirp: improve a bit the debug macros
  slirp: add a callback to log guest errors
  slirp: remove #if notdef dead code
  slirp: remove unused sbflush()
  slirp: NULL is defined by stddef.h
  slirp: remove dead TCP_ACK_HACK code
  slirp: replace ARRAY_SIZE with G_N_ELEMENTS
  net: do not depend on slirp internals
  glib-compat: add g_spawn_async_with_fds() fallback
  slirp: simplify fork_exec()
  slirp: replace error_report() with g_critical()
  slirp: drop <Vista compatibility
  slirp: rename exec_list
  slirp: use virtual time for packet expiration
  slirp: replace a fprintf with g_critical()
  slirp: replace some fprintf() with DEBUG_MISC
  slirp: replace a DEBUG block with WITH_ICMP_ERROR_MSG
  slirp: no need to make DPRINTF conditional on DEBUG
  slirp: always build with debug statements
  slirp: introduce SLIRP_DEBUG environment variable
  slirp: use %p for pointers format
  slirp: remove remaining DEBUG blocks
  slirp: replace DEBUG_ARGS with DEBUG_ARG
  slirp: factor out guestfwd addition checks
  slirp: add clock_get_ns() callback
  build-sys: use a separate slirp-obj-y && slirp.mo
  slirp: set G_LOG_DOMAIN
  slirp: call into g_debug() for DEBUG macros

Prasad J Pandit (1):
  slirp: check data length while emulating ident function

Samuel Thibault (2):
  slirp: Enable fork_exec support on Windows
  slirp: Mark debugging calls as unlikely

 Makefile              |   5 +-
 Makefile.objs         |   4 +-
 Makefile.target       |   5 +-
 include/glib-compat.h |  56 +++++++++
 net/colo-compare.c    |  11 +-
 net/colo.c            |   1 +
 net/colo.h            |   7 +-
 net/filter-rewriter.c |   9 +-
 net/slirp.c           |  61 +++++----
 net/util.h            |  55 ++++++++
 slirp/Makefile.objs   |  37 +++++-
 slirp/arp_table.c     |  12 +-
 slirp/bootp.c         |  10 +-
 slirp/cksum.c         |   8 +-
 slirp/debug.h         |  47 ++++---
 slirp/dhcpv6.c        |  17 ++-
 slirp/if.c            |   4 +-
 slirp/ip.h            |  10 +-
 slirp/ip6.h           |   3 +-
 slirp/ip6_icmp.c      |  27 ++--
 slirp/ip6_icmp.h      |   6 +-
 slirp/ip6_input.c     |   2 +-
 slirp/ip6_output.c    |   4 +-
 slirp/ip_icmp.c       |  31 ++---
 slirp/ip_input.c      | 200 -----------------------------
 slirp/libslirp.h      |  27 ++--
 slirp/main.h          |  33 -----
 slirp/mbuf.c          |   2 +-
 slirp/mbuf.h          |   1 -
 slirp/misc.c          | 286 +++++++++++++++++-------------------------
 slirp/misc.h          |  13 +-
 slirp/ncsi.c          |   4 +-
 slirp/ndp_table.c     |  32 +++--
 slirp/sbuf.h          |   1 -
 slirp/slirp.c         | 177 +++++++++++++-------------
 slirp/slirp.h         |  45 ++-----
 slirp/slirp_config.h  |  86 -------------
 slirp/socket.c        |  53 +++-----
 slirp/socket.h        |   2 +-
 slirp/tcp.h           |   4 +-
 slirp/tcp_input.c     |  84 ++-----------
 slirp/tcp_output.c    |   2 +-
 slirp/tcp_subr.c      |  22 ++--
 slirp/tcp_timer.c     |   2 +-
 slirp/tftp.c          |   7 +-
 slirp/trace-events    |   5 +
 slirp/udp.c           |   5 +-
 slirp/udp6.c          |  11 +-
 stubs/slirp.c         |   2 +-
 49 files changed, 603 insertions(+), 935 deletions(-)
 delete mode 100644 slirp/slirp_config.h
 create mode 100644 slirp/trace-events

--
2.20.1

# gpg: Signature made Mon 14 Jan 2019 22:52:32 GMT
# gpg:                using RSA key DB550E89F0FA54F3
# gpg: Good signature from "Samuel Thibault <samuel.thibault@aquilenet.fr>"
# gpg:                 aka "Samuel Thibault <sthibault@debian.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@gnu.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@inria.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@labri.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@ens-lyon.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@u-bordeaux.fr>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 900C B024 B679 31D4 0F82  304B D017 8C76 7D06 9EE6
#      Subkey fingerprint: E61D BB15 D417 2BDE C97E  92D9 DB55 0E89 F0FA 54F3

* remotes/thibault/tags/samuel-thibault: (65 commits)
  slirp: check data length while emulating ident function
  slirp: Mark debugging calls as unlikely
  slirp: call into g_debug() for DEBUG macros
  slirp: set G_LOG_DOMAIN
  build-sys: use a separate slirp-obj-y && slirp.mo
  slirp: add clock_get_ns() callback
  slirp: factor out guestfwd addition checks
  slirp: replace DEBUG_ARGS with DEBUG_ARG
  slirp: remove remaining DEBUG blocks
  slirp: use %p for pointers format
  slirp: introduce SLIRP_DEBUG environment variable
  slirp: always build with debug statements
  slirp: no need to make DPRINTF conditional on DEBUG
  slirp: replace a DEBUG block with WITH_ICMP_ERROR_MSG
  slirp: replace some fprintf() with DEBUG_MISC
  slirp: replace a fprintf with g_critical()
  slirp: use virtual time for packet expiration
  slirp: rename exec_list
  slirp: drop <Vista compatibility
  slirp: Enable fork_exec support on Windows
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-01-15 18:32:57 +00:00
49 changed files with 606 additions and 938 deletions
+3 -2
View File
@@ -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))
+2 -2
View File
@@ -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
+4 -1
View File
@@ -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
+56
View File
@@ -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)
/*
+6 -5
View File
@@ -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);
+1
View File
@@ -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)
{
+3 -4
View File
@@ -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);
+5 -4
View File
@@ -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__,
+29 -32
View File
@@ -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);
}
}
+55
View File
@@ -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 */
+32 -5
View File
@@ -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\"
+6 -6
View File
@@ -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;
}
}
+3 -7
View File
@@ -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 */
+2 -6
View File
@@ -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
+24 -17
View File
@@ -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); }
#define DEBUG_CALL(fmt, ...) do { \
if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
g_debug(fmt "...", ##__VA_ARGS__); \
} \
} while (0)
#else
#define DEBUG_ARG(fmt, ...) do { \
if (G_UNLIKELY(slirp_debug & DBG_CALL)) { \
g_debug(" " fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DEBUG_CALL(x)
#define DEBUG_ARG(x, y)
#define DEBUG_ARGS(x)
#define DEBUG_MISC(x)
#define DEBUG_ERROR(x)
#define DEBUG_MISC(fmt, ...) do { \
if (G_UNLIKELY(slirp_debug & DBG_MISC)) { \
g_debug(fmt, ##__VA_ARGS__); \
} \
} while (0)
#endif
#define DEBUG_ERROR(fmt, ...) do { \
if (G_UNLIKELY(slirp_debug & DBG_ERROR)) { \
g_debug(fmt, ##__VA_ARGS__); \
} \
} while (0)
#endif /* DEBUG_H_ */
+8 -9
View File
@@ -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]);
}
}
+1 -3
View File
@@ -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;
+6 -4
View File
@@ -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;
+2 -1
View File
@@ -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 */
+12 -15
View File
@@ -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;

Some files were not shown because too many files have changed in this diff Show More