static void usb_net_handle_dataout(USBNetState *s, USBPacket *p) { int sz = sizeof(s->out_buf) - s->out_ptr; struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *) s->out_buf; uint32_t len; #ifdef TRAFFIC_DEBUG fprintf(stderr, "usbnet: data out len %zu\n", p->iov.size); iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", p->iov.size); #endif if (sz > p->iov.size) { sz = p->iov.size; } usb_packet_copy(p, &s->out_buf[s->out_ptr], sz); s->out_ptr += sz; if (!is_rndis(s)) { if (p->iov.size < 64) { qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr); s->out_ptr = 0; } return; } len = le32_to_cpu(msg->MessageLength); if (s->out_ptr < 8 || s->out_ptr < len) { return; } if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) { uint32_t offs = 8 + le32_to_cpu(msg->DataOffset); uint32_t size = le32_to_cpu(msg->DataLength); if (offs + size <= len) qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size); } s->out_ptr -= len; memmove(s->out_buf, &s->out_buf[len], s->out_ptr); }