+ visit_type_int16_t(v,&tp->t_rxtcur, strocat(f, ".t_rxtcur", l),&err);
+ visit_type_int16_t(v,&tp->t_dupacks, strocat(f, ".t_dupacks", l),&err);
+ visit_type_uint16_t(v,&tp->t_maxseg, strocat(f, ".t_maxseg", l),&err);
+ visit_type_uint8_t(v, (uint8_t *)&tp->t_force, strocat(f, ".t_force",
l),&err);
+ visit_type_uint16_t(v,&tp->t_flags, strocat(f, ".t_flags", l),&err);
+ visit_type_uint32_t(v,&tp->snd_una, strocat(f, ".snd_una", l),&err);
+ visit_type_uint32_t(v,&tp->snd_nxt, strocat(f, ".snd_nxt", l),&err);
+ visit_type_uint32_t(v,&tp->snd_up, strocat(f, ".snd_up", l),&err);
+ visit_type_uint32_t(v,&tp->snd_wl1, strocat(f, ".snd_wl1", l),&err);
+ visit_type_uint32_t(v,&tp->snd_wl2, strocat(f, ".snd_wl2", l),&err);
+ visit_type_uint32_t(v,&tp->iss, strocat(f, ".iss", l),&err);
+ visit_type_uint32_t(v,&tp->snd_wnd, strocat(f, ".snd_wnd", l),&err);
+ visit_type_uint32_t(v,&tp->rcv_wnd, strocat(f, ".rcv_wnd", l),&err);
+ visit_type_uint32_t(v,&tp->rcv_nxt, strocat(f, ".rcv_nxt", l),&err);
+ visit_type_uint32_t(v,&tp->rcv_up, strocat(f, ".rcv_up", l),&err);
+ visit_type_uint32_t(v,&tp->irs, strocat(f, ".irs", l),&err);
+ visit_type_uint32_t(v,&tp->rcv_adv, strocat(f, ".rcv_adv", l),&err);
+ visit_type_uint32_t(v,&tp->snd_max, strocat(f, ".snd_max", l),&err);
+ visit_type_uint32_t(v,&tp->snd_cwnd, strocat(f, ".snd_cwnd", l),&err);
+ visit_type_uint32_t(v,&tp->snd_ssthresh, strocat(f, ".snd_ssthresh",
l),&err);
+ visit_type_int16_t(v,&tp->t_idle, strocat(f, ".t_idle", l),&err);
+ visit_type_int16_t(v,&tp->t_rtt, strocat(f, ".t_rtt", l),&err);
+ visit_type_uint32_t(v,&tp->t_rtseq, strocat(f, ".t_rtseq", l),&err);
+ visit_type_int16_t(v,&tp->t_srtt, strocat(f, ".t_srtt", l),&err);
+ visit_type_int16_t(v,&tp->t_rttvar, strocat(f, ".t_rttvar", l),&err);
+ visit_type_uint16_t(v,&tp->t_rttmin, strocat(f, ".t_rttmin", l),&err);
+ visit_type_uint32_t(v,&tp->max_sndwnd, strocat(f, ".max_sndwnd", l),&err);
+ visit_type_uint8_t(v, (uint8_t *)&tp->t_oobflags, strocat(f, ".t_oobflags",
l),&err);
+ visit_type_uint8_t(v, (uint8_t *)&tp->t_iobc, strocat(f, ".t_iobc",
l),&err);
+ visit_type_int16_t(v,&tp->t_softerror, strocat(f, ".t_softerror", l),&err);
+ visit_type_uint8_t(v,&tp->snd_scale, strocat(f, ".snd_scale", l),&err);
+ visit_type_uint8_t(v,&tp->rcv_scale, strocat(f, ".rcv_scale", l),&err);
+ visit_type_uint8_t(v,&tp->request_r_scale, strocat(f, ".request_r_scale",
l),&err);
+ visit_type_uint8_t(v,&tp->requested_s_scale, strocat(f, ".requested_s_scale",
l),&err);
+ visit_type_uint32_t(v,&tp->ts_recent, strocat(f, ".ts_recent", l),&err);
+ visit_type_uint32_t(v,&tp->ts_recent_age, strocat(f, ".ts_recent_age",
l),&err);
+ visit_type_uint32_t(v,&tp->last_ack_sent, strocat(f, ".last_ack_sent",
l),&err);
}
-static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
+static void slirp_tcp_save(Visitor *v, struct tcpcb *tp, const char *pfield,
Error *err)
{
- uint32_t off;
+ slirp_tcp_visit(v, tp, pfield, err);
+}
- qemu_put_be32(f, sbuf->sb_cc);
- qemu_put_be32(f, sbuf->sb_datalen);
+static void slirp_sbuf_save(Visitor *v, struct sbuf *sbuf, const char *pfield,
Error *err)
+{
+ int32_t off;
+ char f[128];
+ int i, l = 0;
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
+
+ visit_type_uint32_t(v,&sbuf->sb_cc, strocat(f, ".sb_cc", l),&err);
+ visit_type_uint32_t(v,&sbuf->sb_datalen, strocat(f, ".sb_datalen",
l),&err);
off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
- qemu_put_sbe32(f, off);
+ visit_type_int32_t(v,&off, strocat(f, ".sb_wptr_off", l),&err);
off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
- qemu_put_sbe32(f, off);
- qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
+ visit_type_int32_t(v,&off, strocat(f, ".sb_rptr_off", l),&err);
+
+ visit_start_array(v, (void **)&sbuf->sb_data, strocat(f, ".sb_data", l),
+ sbuf->sb_datalen, sizeof(*sbuf->sb_data),&err);
+ for (i = 0; i< sbuf->sb_datalen; i++) {
+ visit_type_uint8_t(v, (uint8_t *)&sbuf->sb_data[i], NULL,&err);
+ }
+ visit_end_array(v,&err);
+}
+
+static void slirp_socket_visit(Visitor *v, struct socket *so, const char
*pfield, Error *err)
+{
+ char f[64];
+ int l = 0;
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
+ visit_type_int32_t(v,&so->so_urgc, strocat(f, ".so_urgc", l),&err);
+ visit_type_uint32_t(v,&so->so_faddr.s_addr, strocat(f, ".so_faddr.s_addr",
l),&err);
+ visit_type_uint32_t(v,&so->so_laddr.s_addr, strocat(f, ".so_urgc",
l),&err);
+ visit_type_uint16_t(v,&so->so_fport, strocat(f, ".so_fport", l),&err);
+ visit_type_uint16_t(v,&so->so_lport, strocat(f, ".so_lport", l),&err);
+ visit_type_uint8_t(v,&so->so_iptos, strocat(f, ".so_iptos", l),&err);
+ visit_type_uint8_t(v,&so->so_emu, strocat(f, ".so_emu", l),&err);
+ visit_type_uint8_t(v,&so->so_type, strocat(f, ".so_type", l),&err);
+ visit_type_int32_t(v,&so->so_state, strocat(f, ".so_state", l),&err);
}
-static void slirp_socket_save(QEMUFile *f, struct socket *so)
+static void slirp_socket_save(Visitor *v, struct socket *so, const char
*pfield, Error *err)
{
- qemu_put_be32(f, so->so_urgc);
- qemu_put_be32(f, so->so_faddr.s_addr);
- qemu_put_be32(f, so->so_laddr.s_addr);
- qemu_put_be16(f, so->so_fport);
- qemu_put_be16(f, so->so_lport);
- qemu_put_byte(f, so->so_iptos);
- qemu_put_byte(f, so->so_emu);
- qemu_put_byte(f, so->so_type);
- qemu_put_be32(f, so->so_state);
- slirp_sbuf_save(f,&so->so_rcv);
- slirp_sbuf_save(f,&so->so_snd);
- slirp_tcp_save(f, so->so_tcpcb);
+ char f[64];
+ int l = 0;
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
+
+ slirp_socket_visit(v, so, f, err);
+
+ slirp_sbuf_save(v,&so->so_rcv, strocat(f, ".so_rcv", l), err);
+ slirp_sbuf_save(v,&so->so_snd, strocat(f, ".so_snd", l), err);
+ slirp_tcp_save(v, so->so_tcpcb, strocat(f, ".so_tcpcb", l), err);
}
-static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
+static void slirp_bootp_visit(Visitor *v, Slirp *slirp, const char *pfield,
Error *err)
{
- int i;
+ int i, j, l;
+ void *ptr;
+ char f[64];
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
+ ptr = slirp->bootp_clients;
+ visit_start_array(v,&ptr, strocat(f, ".bootp_clients", l), NB_BOOTP_CLIENTS,
8,&err);
for (i = 0; i< NB_BOOTP_CLIENTS; i++) {
- qemu_put_be16(f, slirp->bootp_clients[i].allocated);
- qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
+ visit_type_uint16_t(v,&slirp->bootp_clients[i].allocated,
"allocated",&err);
+ ptr = slirp->bootp_clients[i].macaddr;
+ visit_start_array(v,&ptr, "macaddr", 6, 1,&err);
+ for (j = 0; j< 6; j++) {
+ visit_type_uint8_t(v, (uint8_t *)&slirp->bootp_clients[j],
NULL,&err);
+ }
+ visit_end_array(v,&err);
}
+ visit_end_array(v,&err);
}
static void slirp_state_save(QEMUFile *f, void *opaque)
{
Slirp *slirp = opaque;
struct ex_list *ex_ptr;
+ int i = 0;
+ uint8_t padding;
+ Visitor *v = qemu_file_get_output_visitor(f);
+ Error *err = NULL;
+ char id[32];
for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
if (ex_ptr->ex_pty == 3) {
@@ -970,70 +1048,44 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
if (!so)
continue;
- qemu_put_byte(f, 42);
- slirp_socket_save(f, so);
+ padding = SLIRP_DELIMITER;
+ visit_type_uint8_t(v,&padding, "padding",&err);
+ slirp_socket_save(v, so, strocat(id, "so", strlen(id)), err);
}
- qemu_put_byte(f, 0);
+ padding = 0;
+ visit_type_uint8_t(v,&padding, "padding",&err);
+
+ visit_type_uint16_t(v,&slirp->ip_id, "slirp.ip_id",&err);
- qemu_put_be16(f, slirp->ip_id);
+ slirp_bootp_visit(v, slirp, "slirp", err);
- slirp_bootp_save(f, slirp);
+ if (err) {
+ error_report("error saving slirp state: %s", error_get_pretty(err));
+ error_free(err);
+ }
}
-static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
+static void slirp_tcp_load(Visitor *v, struct tcpcb *tp, const char *pfield,
Error *err)
{
- int i;
-
- tp->t_state = qemu_get_sbe16(f);
- for (i = 0; i< TCPT_NTIMERS; i++)
- tp->t_timer[i] = qemu_get_sbe16(f);
- tp->t_rxtshift = qemu_get_sbe16(f);
- tp->t_rxtcur = qemu_get_sbe16(f);
- tp->t_dupacks = qemu_get_sbe16(f);
- tp->t_maxseg = qemu_get_be16(f);
- tp->t_force = qemu_get_sbyte(f);
- tp->t_flags = qemu_get_be16(f);
- tp->snd_una = qemu_get_be32(f);
- tp->snd_nxt = qemu_get_be32(f);
- tp->snd_up = qemu_get_be32(f);
- tp->snd_wl1 = qemu_get_be32(f);
- tp->snd_wl2 = qemu_get_be32(f);
- tp->iss = qemu_get_be32(f);
- tp->snd_wnd = qemu_get_be32(f);
- tp->rcv_wnd = qemu_get_be32(f);
- tp->rcv_nxt = qemu_get_be32(f);
- tp->rcv_up = qemu_get_be32(f);
- tp->irs = qemu_get_be32(f);
- tp->rcv_adv = qemu_get_be32(f);
- tp->snd_max = qemu_get_be32(f);
- tp->snd_cwnd = qemu_get_be32(f);
- tp->snd_ssthresh = qemu_get_be32(f);
- tp->t_idle = qemu_get_sbe16(f);
- tp->t_rtt = qemu_get_sbe16(f);
- tp->t_rtseq = qemu_get_be32(f);
- tp->t_srtt = qemu_get_sbe16(f);
- tp->t_rttvar = qemu_get_sbe16(f);
- tp->t_rttmin = qemu_get_be16(f);
- tp->max_sndwnd = qemu_get_be32(f);
- tp->t_oobflags = qemu_get_byte(f);
- tp->t_iobc = qemu_get_byte(f);
- tp->t_softerror = qemu_get_sbe16(f);
- tp->snd_scale = qemu_get_byte(f);
- tp->rcv_scale = qemu_get_byte(f);
- tp->request_r_scale = qemu_get_byte(f);
- tp->requested_s_scale = qemu_get_byte(f);
- tp->ts_recent = qemu_get_be32(f);
- tp->ts_recent_age = qemu_get_be32(f);
- tp->last_ack_sent = qemu_get_be32(f);
+ slirp_tcp_visit(v, tp, pfield, err);
+
tcp_template(tp);
}
-static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
+static int slirp_sbuf_load(Visitor *v, struct sbuf *sbuf, const char *pfield,
Error *err)
{
uint32_t off, sb_cc, sb_datalen;
+ int l = 0, i;
+ char f[64];
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
- sb_cc = qemu_get_be32(f);
- sb_datalen = qemu_get_be32(f);
+ visit_type_uint32_t(v,&sb_cc, strocat(f, ".sb_cc", l),&err);
+ visit_type_uint32_t(v,&sb_datalen, strocat(f, ".sb_datalen", l),&err);
sbreserve(sbuf, sb_datalen);
@@ -1042,61 +1094,68 @@ static int slirp_sbuf_load(QEMUFile *f, struct sbuf
*sbuf)
sbuf->sb_cc = sb_cc;
- off = qemu_get_sbe32(f);
+ visit_type_uint32_t(v,&off, strocat(f, ".sb_wptr_off", l),&err);
sbuf->sb_wptr = sbuf->sb_data + off;
- off = qemu_get_sbe32(f);
+ visit_type_uint32_t(v,&off, strocat(f, ".sb_rptr_off", l),&err);
sbuf->sb_rptr = sbuf->sb_data + off;
- qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
+
+ visit_start_array(v, (void **)&sbuf->sb_data, strocat(f, ".sb_data", l),
+ sbuf->sb_datalen, sizeof(*sbuf->sb_data),&err);
+ for (i = 0; i< sbuf->sb_datalen; i++) {
+ visit_type_uint8_t(v, (uint8_t *)&sbuf->sb_data[i], NULL,&err);
+ }
+ visit_end_array(v,&err);
return 0;
}
-static int slirp_socket_load(QEMUFile *f, struct socket *so)
+static int slirp_socket_load(Visitor *v, struct socket *so, const char
*pfield, Error *err)
{
+ char f[64];
+ int l = 0;
+
+ if (pfield) {
+ assert(strlen(pfield)< sizeof(f));
+ strcpy(f, pfield);
+ l = strlen(f);
+ }
+
+ assert(v);
if (tcp_attach(so)< 0)
return -ENOMEM;
- so->so_urgc = qemu_get_be32(f);
- so->so_faddr.s_addr = qemu_get_be32(f);
- so->so_laddr.s_addr = qemu_get_be32(f);
- so->so_fport = qemu_get_be16(f);
- so->so_lport = qemu_get_be16(f);
- so->so_iptos = qemu_get_byte(f);
- so->so_emu = qemu_get_byte(f);
- so->so_type = qemu_get_byte(f);
- so->so_state = qemu_get_be32(f);
- if (slirp_sbuf_load(f,&so->so_rcv)< 0)
+ slirp_socket_visit(v, so, pfield, err);
+
+ if (slirp_sbuf_load(v,&so->so_rcv, strocat(f, ".so_rcv", l), err)< 0)
return -ENOMEM;
- if (slirp_sbuf_load(f,&so->so_snd)< 0)
+ if (slirp_sbuf_load(v,&so->so_snd, strocat(f, ".so_snd", l), err)< 0)
return -ENOMEM;
- slirp_tcp_load(f, so->so_tcpcb);
+ slirp_tcp_load(v, so->so_tcpcb, strocat(f, ".so_tcpcb", l), err);
return 0;
}
-static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
-{
- int i;
-
- for (i = 0; i< NB_BOOTP_CLIENTS; i++) {
- slirp->bootp_clients[i].allocated = qemu_get_be16(f);
- qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
- }
-}
-
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
{
Slirp *slirp = opaque;
struct ex_list *ex_ptr;
+ Visitor *v = qemu_file_get_input_visitor(f);
+ Error *err = NULL;
+ char id[32];
+ uint8_t padding, i = 0;
- while (qemu_get_byte(f)) {
+ visit_type_uint8_t(v,&padding, "padding",&err);
+
+ while (padding == SLIRP_DELIMITER) {
int ret;
struct socket *so = socreate(slirp);
if (!so)
return -ENOMEM;
- ret = slirp_socket_load(f, so);
+ sprintf(id, "slirp[%d]", i++);
+
+ ret = slirp_socket_load(v, so, strocat(id, "so", strlen(id)), err);
if (ret< 0)
return ret;
@@ -1118,12 +1177,19 @@ static int slirp_state_load(QEMUFile *f, void *opaque,
int version_id)
so->extra = (void *)ex_ptr->ex_exec;
}
+
if (version_id>= 2) {
- slirp->ip_id = qemu_get_be16(f);
+ visit_type_uint16_t(v,&slirp->ip_id, "slirp.ip_id",&err);
}
if (version_id>= 3) {
- slirp_bootp_load(f, slirp);
+ slirp_bootp_visit(v, slirp, "slirp", err);
+ }
+
+ if (err) {
+ error_report("error loading slirp state: %s", error_get_pretty(err));
+ error_free(err);
+ return -EINVAL;
}
return 0;