void HoRNDIS::receivePacket(void *packet, UInt32 size) { mbuf_t m; UInt32 submit; IOReturn rv; LOG(V_DEBUG, "sz %d", (int)size); if (size > MAX_BLOCK_SIZE) { LOG(V_ERROR, "packet size error, packet dropped"); fpNetStats->inputErrors++; return; } while (size) { struct rndis_data_hdr *hdr = (struct rndis_data_hdr *)packet; uint32_t msg_len, data_ofs, data_len; msg_len = le32_to_cpu(hdr->msg_len); data_ofs = le32_to_cpu(hdr->data_offset); data_len = le32_to_cpu(hdr->data_len); if (hdr->msg_type != RNDIS_MSG_PACKET) { LOG(V_ERROR, "non-PACKET over data channel? (msg_type %08x)", hdr->msg_type); return; } if (hdr->msg_len > size) { LOG(V_ERROR, "msg_len too big?"); return; } if ((data_ofs + data_len + 8) > msg_len) { LOG(V_ERROR, "data bigger than msg?"); return; } m = allocatePacket(data_len); if (!m) { LOG(V_ERROR, "allocatePacket for data_len %d failed", data_len); fpNetStats->inputErrors++; return; } rv = mbuf_copyback(m, 0, data_len, (char *)packet + data_ofs + 8, MBUF_WAITOK); if (rv) { LOG(V_ERROR, "mbuf_copyback failed, rv %08x", rv); fpNetStats->inputErrors++; freePacket(m); return; } submit = fNetworkInterface->inputPacket(m, data_len); LOG(V_DEBUG, "submitted pkt sz %d", data_len); fpNetStats->inputPackets++; size -= hdr->msg_len; packet = (char *)packet + hdr->msg_len; } }
void net_habitue_device_SC101::resolve() { KDEBUG("resolving"); clock_get_uptime(&_lastResolve); sockaddr_in addr; bzero(&addr, sizeof(addr)); addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(PSAN_PORT); addr.sin_addr.s_addr = INADDR_BROADCAST; psan_resolve_t req; bzero(&req, sizeof(req)); req.ctrl.cmd = PSAN_RESOLVE; req.ctrl.seq = ((net_habitue_driver_SC101 *)getProvider())->getSequenceNumber(); strncpy(req.id, getID()->getCStringNoCopy(), sizeof(req.id)); outstanding *out = IONewZero(outstanding, 1); out->seq = ntohs(req.ctrl.seq); out->len = sizeof(psan_resolve_response_t); out->cmd = PSAN_RESOLVE_RESPONSE; out->packetHandler = OSMemberFunctionCast(PacketHandler, this, &net_habitue_device_SC101::handleResolvePacket); out->timeoutHandler = OSMemberFunctionCast(TimeoutHandler, this, &net_habitue_device_SC101::handleResolveTimeout); out->target = this; out->timeout_ms = RESOLVE_TIMEOUT_MS; mbuf_t m; if (mbuf_allocpacket(MBUF_WAITOK, sizeof(psan_resolve_t), NULL, &m) != 0) KINFO("mbuf_allocpacket failed!"); // TODO(iwade) handle if (mbuf_copyback(m, 0, sizeof(req), &req, MBUF_WAITOK) != 0) KINFO("mbuf_copyback failed!"); // TODO(iwade) handle ((net_habitue_driver_SC101 *)getProvider())->sendPacket(&addr, m, out); }
void net_habitue_device_SC101::doSubmitIO(outstanding_io *io) { bool isWrite = (io->buffer->getDirection() == kIODirectionOut); UInt32 ioLen = (io->nblks * SECTOR_SIZE); mbuf_t m; retryResolve(); if (isWrite) { KDEBUG("%p write %d %d (%d)", io, io->block, io->nblks, _outstandingCount); psan_put_t req; bzero(&req, sizeof(req)); req.ctrl.cmd = PSAN_PUT; req.ctrl.seq = ((net_habitue_driver_SC101 *)getProvider())->getSequenceNumber(); req.ctrl.len_power = POWER_OF_2(ioLen); req.sector = htonl(io->block); if (mbuf_allocpacket(MBUF_WAITOK, sizeof(req) + ioLen, NULL, &m) != 0) KINFO("mbuf_allocpacket failed!"); // TODO(iwade) handle if (mbuf_copyback(m, 0, sizeof(req), &req, MBUF_WAITOK) != 0) KINFO("mbuf_copyback failed!"); // TODO(iwade) handle if (!mbuf_buffer(io->buffer, 0, m, sizeof(req), ioLen)) KINFO("mbuf_buffer failed"); // TODO(iwade) handle io->outstanding.seq = ntohs(req.ctrl.seq); io->outstanding.len = sizeof(psan_put_response_t); io->outstanding.cmd = PSAN_PUT_RESPONSE; } else { KDEBUG("%p read %d %d (%d)", io, io->block, io->nblks, _outstandingCount); psan_get_t req; bzero(&req, sizeof(req)); req.ctrl.cmd = PSAN_GET; req.ctrl.seq = ((net_habitue_driver_SC101 *)getProvider())->getSequenceNumber(); req.ctrl.len_power = POWER_OF_2(ioLen); req.sector = htonl(io->block); if (mbuf_allocpacket(MBUF_WAITOK, sizeof(req), NULL, &m) != 0) KINFO("mbuf_allocpacket failed!"); // TODO(iwade) handle if (mbuf_copyback(m, 0, sizeof(req), &req, MBUF_WAITOK) != 0) KINFO("mbuf_copyback failed!"); // TODO(iwade) handle io->outstanding.seq = ntohs(req.ctrl.seq); io->outstanding.len = sizeof(psan_get_response_t) + ioLen; io->outstanding.cmd = PSAN_GET_RESPONSE; } io->outstanding.packetHandler = OSMemberFunctionCast(PacketHandler, this, &net_habitue_device_SC101::handleAsyncIOPacket); io->outstanding.timeoutHandler = OSMemberFunctionCast(TimeoutHandler, this, &net_habitue_device_SC101::handleAsyncIOTimeout); io->outstanding.target = this; io->outstanding.ctx = io; io->outstanding.timeout_ms = io->timeout_ms; ((net_habitue_driver_SC101 *)getProvider())->sendPacket((sockaddr_in *)io->addr->getBytesNoCopy(), m, &io->outstanding); }