mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user