From 16e5f5828b8b2cbdbddb35c04c943d26525d9d66 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 19 May 2024 18:32:18 +0200 Subject: [PATCH] Builtin slirp: Added some replacement macros for glib ones. Now slirp_new() checks correctness of config settings. Some other small additions and cleanups. --- bochs/iodev/network/eth_slirp.cc | 2 +- bochs/iodev/network/slirp/bootp.cc | 28 ++++++++++---------------- bochs/iodev/network/slirp/compat.h | 3 +++ bochs/iodev/network/slirp/sbuf.cc | 2 +- bochs/iodev/network/slirp/slirp.cc | 27 ++++++++++++++++++++----- bochs/iodev/network/slirp/tcp_input.cc | 1 + bochs/iodev/network/slirp/tcp_subr.cc | 14 ++++++++++--- 7 files changed, 50 insertions(+), 27 deletions(-) diff --git a/bochs/iodev/network/eth_slirp.cc b/bochs/iodev/network/eth_slirp.cc index 788c9a19e..5bfe5a227 100644 --- a/bochs/iodev/network/eth_slirp.cc +++ b/bochs/iodev/network/eth_slirp.cc @@ -293,7 +293,7 @@ bx_slirp_pktmover_c::bx_slirp_pktmover_c(const char *netif, #if BX_HAVE_LIBSLIRP BX_INFO(("slirp network driver (libslirp version %s)", slirp_version_string())); #else - BX_INFO(("slirp network driver")); + BX_INFO(("slirp network driver (based on libslirp version %s)", slirp_version_string())); debug_switches = 0; #endif diff --git a/bochs/iodev/network/slirp/bootp.cc b/bochs/iodev/network/slirp/bootp.cc index 85b1adcf4..2943fb9b3 100644 --- a/bochs/iodev/network/slirp/bootp.cc +++ b/bochs/iodev/network/slirp/bootp.cc @@ -114,7 +114,6 @@ static void dhcp_decode(Slirp *slirp, const struct bootp_t *bp, const uint8_t *p; uint16_t defsize, maxsize; int len, tag; - char msg[80]; memset(opts, 0, sizeof(dhcp_options_t)); @@ -136,7 +135,7 @@ static void dhcp_decode(Slirp *slirp, const struct bootp_t *bp, if (p + len > bp_end) { break; } - DPRINTF("dhcp: tag=%d len=%d\n", tag, len); + DPRINTF("dhcp: tag=%d len=%d", tag, len); switch(tag) { case RFC2132_MSG_TYPE: @@ -179,14 +178,12 @@ static void dhcp_decode(Slirp *slirp, const struct bootp_t *bp, memcpy(&maxsize, p, len); defsize = sizeof(struct bootp_t) + DHCP_OPT_LEN - sizeof(struct ip) - sizeof(struct udphdr); if (ntohs(maxsize) < defsize) { - sprintf(msg, "DHCP server: RFB2132_MAX_SIZE=%u not supported yet", ntohs(maxsize)); - slirplog_error(msg); + slirplog_error("DHCP server: RFB2132_MAX_SIZE=%u not supported yet", ntohs(maxsize)); } } break; default: - sprintf(msg, "DHCP server: option %d not supported yet", tag); - slirplog_error(msg); + slirplog_error("DHCP server: option %d not supported yet", tag); break; } p += len; @@ -211,15 +208,13 @@ static void bootp_reply(Slirp *slirp, uint8_t *q, *end, *pp, plen; uint8_t client_ethaddr[ETH_ALEN]; dhcp_options_t dhcp_opts; - char msg[80]; /* extract exact DHCP msg type */ dhcp_decode(slirp, bp, bp_end, &dhcp_opts); DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_opts.msg_type); - if (dhcp_opts.req_addr.s_addr != htonl(0L)) - DPRINTF(" req_addr=%08x\n", ntohl(dhcp_opts.req_addr.s_addr)); - else - DPRINTF("\n"); + if (dhcp_opts.req_addr.s_addr != htonl(0L)) { + DPRINTF(" req_addr=%08x", ntohl(dhcp_opts.req_addr.s_addr)); + } if (dhcp_opts.msg_type == 0) dhcp_opts.msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ @@ -252,7 +247,7 @@ static void bootp_reply(Slirp *slirp, new_addr: bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr); if (!bc) { - DPRINTF("no address left\n"); + DPRINTF("no address left"); return; } } @@ -298,7 +293,7 @@ static void bootp_reply(Slirp *slirp, q += 4; if (bc) { - DPRINTF("%s addr=%08x\n", + DPRINTF("%s addr=%08x", (dhcp_opts.msg_type == DHCPDISCOVER) ? "offered" : "ack'ed", ntohl(daddr.sin_addr.s_addr)); @@ -434,9 +429,8 @@ static void bootp_reply(Slirp *slirp, // Already handled on top of reply break; default: - sprintf(msg, "DHCP server: requested parameter %u not supported yet", - *(pp-1)); - slirplog_error(msg); + slirplog_error("DHCP server: requested parameter %u not supported yet", + *(pp-1)); } } @@ -472,7 +466,7 @@ static void bootp_reply(Slirp *slirp, } else { static const char nak_msg[] = "requested address not available"; - DPRINTF("nak'ed addr=%08x\n", ntohl(dhcp_opts.req_addr.s_addr)); + DPRINTF("nak'ed addr=%08x", ntohl(dhcp_opts.req_addr.s_addr)); *q++ = RFC2132_MSG_TYPE; *q++ = 1; diff --git a/bochs/iodev/network/slirp/compat.h b/bochs/iodev/network/slirp/compat.h index 779f273ae..767996935 100644 --- a/bochs/iodev/network/slirp/compat.h +++ b/bochs/iodev/network/slirp/compat.h @@ -29,6 +29,9 @@ #define SLIRP_N_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) #define slirp_rand_int_range(min, max) ((rand() % (max - min)) + min) +#define slirp_warn_if_fail(cond) if (!(cond)) slirplog_error("condition " #cond " failed") +#define slirp_return_if_fail(cond) if (!(cond)) return +#define slirp_return_val_if_fail(cond, retval) if (!(cond)) return retval #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/bochs/iodev/network/slirp/sbuf.cc b/bochs/iodev/network/slirp/sbuf.cc index e17ad8909..4eaf18597 100644 --- a/bochs/iodev/network/slirp/sbuf.cc +++ b/bochs/iodev/network/slirp/sbuf.cc @@ -18,7 +18,7 @@ bool sbdrop(struct sbuf *sb, size_t num) { int limit = sb->sb_datalen / 2; -// g_warn_if_fail(num <= sb->sb_cc); + slirp_warn_if_fail(num <= sb->sb_cc); if (num > sb->sb_cc) num = sb->sb_cc; diff --git a/bochs/iodev/network/slirp/slirp.cc b/bochs/iodev/network/slirp/slirp.cc index 3203f801e..4baa1c4de 100644 --- a/bochs/iodev/network/slirp/slirp.cc +++ b/bochs/iodev/network/slirp/slirp.cc @@ -547,6 +547,8 @@ static void slirp_init_once(void) loopback_addr.s_addr = htonl(INADDR_LOOPBACK); loopback_mask = htonl(IN_CLASSA_NET); + + slirp_debug = 0; } static void ra_timer_handler_cb(void *opaque) @@ -558,7 +560,7 @@ static void ra_timer_handler_cb(void *opaque) void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque) { -// g_return_if_fail(id >= 0 && id < SLIRP_TIMER_NUM); + slirp_return_if_fail(id >= 0 && id < SLIRP_TIMER_NUM); switch (id) { case SLIRP_TIMER_RA: @@ -571,7 +573,7 @@ void slirp_handle_timer(Slirp *slirp, SlirpTimerId id, void *cb_opaque) void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque) { -// g_return_val_if_fail(id >= 0 && id < SLIRP_TIMER_NUM, NULL); + slirp_return_val_if_fail(id >= 0 && id < SLIRP_TIMER_NUM, NULL); if (slirp->cfg_version >= 4 && slirp->cb->timer_new_opaque) { return slirp->cb->timer_new_opaque(id, cb_opaque, slirp->opaque); @@ -579,7 +581,7 @@ void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque) switch (id) { case SLIRP_TIMER_RA: -// g_return_val_if_fail(cb_opaque == NULL, NULL); + slirp_return_val_if_fail(cb_opaque == NULL, NULL); return slirp->cb->timer_new(ra_timer_handler_cb, slirp, slirp->opaque); default: @@ -589,7 +591,20 @@ void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque) Slirp *slirp_new(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque) { - Slirp *slirp = (Slirp*)malloc(sizeof(Slirp)); + Slirp *slirp; + + slirp_return_val_if_fail(cfg != NULL, NULL); + slirp_return_val_if_fail(cfg->version >= SLIRP_CONFIG_VERSION_MIN, NULL); + slirp_return_val_if_fail(cfg->version <= SLIRP_CONFIG_VERSION_MAX, NULL); + slirp_return_val_if_fail(cfg->if_mtu >= IF_MTU_MIN || cfg->if_mtu == 0, NULL); + slirp_return_val_if_fail(cfg->if_mtu <= IF_MTU_MAX, NULL); + slirp_return_val_if_fail(cfg->if_mru >= IF_MRU_MIN || cfg->if_mru == 0, NULL); + slirp_return_val_if_fail(cfg->if_mru <= IF_MRU_MAX, NULL); + slirp_return_val_if_fail(!cfg->bootfile || + (strlen(cfg->bootfile) < + G_SIZEOF_MEMBER(struct bootp_t, bp_file)), NULL); + + slirp = (Slirp*)malloc(sizeof(Slirp)); memset(slirp, 0, sizeof(Slirp)); slirp_init_once(); @@ -724,6 +739,7 @@ void slirp_cleanup(Slirp *slirp) } ip_cleanup(slirp); + ip6_cleanup(slirp); m_cleanup(slirp); free(slirp->vdomainname); @@ -1605,7 +1621,8 @@ void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len) if (ret < 0) { slirplog_error("Failed to send packet"); } else if ((size_t)ret < len) { - slirplog_error("send_packet() didn't send all data"); + DEBUG_ERROR("send_packet() didn't send all data: %ld < %lu", (long)ret, + (unsigned long)len); } } diff --git a/bochs/iodev/network/slirp/tcp_input.cc b/bochs/iodev/network/slirp/tcp_input.cc index e4cce85ab..4b76d7414 100644 --- a/bochs/iodev/network/slirp/tcp_input.cc +++ b/bochs/iodev/network/slirp/tcp_input.cc @@ -1532,6 +1532,7 @@ int tcp_mss(struct tcpcb *tp, unsigned offer) default: slirplog_error("Unknown protocol"); } + if (offer) mss = MIN(mss, (int)offer); mss = MAX(mss, 32); diff --git a/bochs/iodev/network/slirp/tcp_subr.cc b/bochs/iodev/network/slirp/tcp_subr.cc index 1c949bf19..3d7fca9d5 100644 --- a/bochs/iodev/network/slirp/tcp_subr.cc +++ b/bochs/iodev/network/slirp/tcp_subr.cc @@ -658,10 +658,12 @@ int tcp_emu(struct socket *so, struct mbuf *m) tmpso->so_fport == n1) { if (getsockname(tmpso->s, (struct sockaddr *)&addr, &addrlen) == 0) - n2 = ntohs(addr.sin_port); + n2 = addr.sin_port; break; } } + NTOHS(n1); + NTOHS(n2); } so_rcv->sb_cc = snprintf(so_rcv->sb_data, so_rcv->sb_datalen, "%d,%d\r\n", n1, n2); @@ -893,6 +895,9 @@ int tcp_emu(struct socket *so, struct mbuf *m) break; case 5: + if (bptr == m->m_data + m->m_len - 1) + return 1; /* We need two bytes */ + /* * The difference between versions 1.0 and * 2.0 is here. For future versions of @@ -908,8 +913,11 @@ int tcp_emu(struct socket *so, struct mbuf *m) /* This is the field containing the port * number that RA-player is listening to. */ - lport = (((uint8_t*)bptr)[0] << 8) - + ((uint8_t *)bptr)[1]; + + if (bptr == m->m_data + m->m_len - 1) + return 1; /* We need two bytes */ + + lport = (((uint8_t*)bptr)[0] << 8) + ((uint8_t *)bptr)[1]; if (lport < 6970) lport += 256; /* don't know why */ if (lport < 6970 || lport > 7170)