* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <slirp.h>
+#include "qemu/osdep.h"
+#include "slirp.h"
+
+#if defined(_WIN32)
+/* Windows ntohl() returns an u_long value.
+ * Add a type cast to match the format strings. */
+# define ntohl(n) ((uint32_t)ntohl(n))
+#endif
/* XXX: only DHCP is supported */
if (p >= p_end)
break;
len = *p++;
+ if (p + len > p_end) {
+ break;
+ }
DPRINTF("dhcp: tag=%d len=%d\n", tag, len);
switch(tag) {
struct in_addr preq_addr;
int dhcp_msg_type, val;
uint8_t *q;
+ uint8_t *end;
uint8_t client_ethaddr[ETH_ALEN];
/* extract exact DHCP msg type */
dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
if (preq_addr.s_addr != htonl(0L))
- DPRINTF(" req_addr=%08x\n", ntohl(preq_addr.s_addr));
+ DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
else
DPRINTF("\n");
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
q = rbp->bp_vend;
+ end = (uint8_t *)&rbp[1];
memcpy(q, rfc1533_cookie, 4);
q += 4;
if (bc) {
- DPRINTF("%s addr=%08x\n",
+ DPRINTF("%s addr=%08" PRIx32 "\n",
(dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
ntohl(daddr.sin_addr.s_addr));
if (*slirp->client_hostname) {
val = strlen(slirp->client_hostname);
- *q++ = RFC1533_HOSTNAME;
- *q++ = val;
- memcpy(q, slirp->client_hostname, val);
- q += val;
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting host name option.");
+ } else {
+ *q++ = RFC1533_HOSTNAME;
+ *q++ = val;
+ memcpy(q, slirp->client_hostname, val);
+ q += val;
+ }
+ }
+
+ if (slirp->vdomainname) {
+ val = strlen(slirp->vdomainname);
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting domain name option.");
+ } else {
+ *q++ = RFC1533_DOMAINNAME;
+ *q++ = val;
+ memcpy(q, slirp->vdomainname, val);
+ q += val;
+ }
+ }
+
+ if (slirp->tftp_server_name) {
+ val = strlen(slirp->tftp_server_name);
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting tftp-server-name option.");
+ } else {
+ *q++ = RFC2132_TFTP_SERVER_NAME;
+ *q++ = val;
+ memcpy(q, slirp->tftp_server_name, val);
+ q += val;
+ }
+ }
+
+ if (slirp->vdnssearch) {
+ val = slirp->vdnssearch_len;
+ if (q + val >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting domain-search option.");
+ } else {
+ memcpy(q, slirp->vdnssearch, val);
+ q += val;
+ }
}
} else {
static const char nak_msg[] = "requested address not available";
- DPRINTF("nak'ed addr=%08x\n", ntohl(preq_addr.s_addr));
+ DPRINTF("nak'ed addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
*q++ = RFC2132_MSG_TYPE;
*q++ = 1;
memcpy(q, nak_msg, sizeof(nak_msg) - 1);
q += sizeof(nak_msg) - 1;
}
+ assert(q < end);
*q = RFC1533_END;
daddr.sin_addr.s_addr = 0xffffffffu;
m->m_len = sizeof(struct bootp_t) -
sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
void bootp_input(struct mbuf *m)