示例#1
0
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;
	}
}
示例#2
0
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);
}
示例#3
0
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);
}