Example #1
0
bool WSocket::tcpRecvAll(SOCKET s, void *buf, int bufSize, DWORD timeout)
{
  int len;

  do
  {
    if((len = tcpRecv(s, buf, bufSize, timeout)) <= 0)return false;

    buf      = ((LPBYTE)buf) + len;
    bufSize -= len;
  }
  while(bufSize > 0);

  return (bufSize == 0);
}
Example #2
0
/**
 * Process an incoming IPv4 packet.
 * @param pkt pointer to the incoming packet
 * @return OK if packet was processed succesfully, otherwise SYSERR
 */
syscall ipv4Recv(struct packet *pkt)
{
    struct ipv4Pkt *ip;
    struct netaddr dst;
    struct netaddr src;
    ushort iplen;

    /* Error check pointers */
    if (NULL == pkt)
    {
        return SYSERR;
    }

    /* Setup pointer to IPv4 header */
    pkt->nethdr = pkt->curr;
    ip = (struct ipv4Pkt *)pkt->curr;

    /* Verify the IP packet is valid */
    if (FALSE == ipv4RecvValid(ip))
    {
        IPv4_TRACE("Invalid packet");
        netFreebuf(pkt);
        return SYSERR;
    }

    /* Obtain destination and source IP addresses */
    dst.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    memcpy(dst.addr, ip->dst, dst.len);
    src.type = NETADDR_IPv4;
    src.len = IPv4_ADDR_LEN;
    memcpy(src.addr, ip->src, src.len);

    /* If packet is not destined for one of our network interfaces,
     * then attempt to route the packet */
    if (FALSE == ipv4RecvDemux(&dst))
    {
        IPv4_TRACE("Packet sent to routing subsystem");

#if NETEMU
        /* Run the packet through the network emulator if enabled */
        return netemu(pkt);
#else
        return rtRecv(pkt);
#endif
    }

    /* Check if packet is fragmented */
    if ((IPv4_FLAG_MF & net2hs(ip->flags_froff))
        || (0 != (net2hs(ip->flags_froff) & IPv4_FROFF)))
    {
        // TODO: Handle fragmenting of packet
        // TODO: Should send icmp time exceeded
        // return ipRecvSendFrag(pkt, &dst);
        IPv4_TRACE("Packet fragmented");
        netFreebuf(pkt);
        return SYSERR;
    }

    /* The Ethernet driver pads packets less than 60 bytes in length.
     * If the packet length returned from the Ethernet driver (pkt->len)
     * does not agree with the packet headers, adjust the packet length 
     * to remove padding. */
    iplen = net2hs(ip->len);
    if ((pkt->len - pkt->nif->linkhdrlen) > iplen)
    {
        pkt->len = pkt->nif->linkhdrlen + iplen;
    }

    /* Move current pointer to application level header */
    pkt->curr += ((ip->ver_ihl & IPv4_IHL) << 2);

    IPv4_TRACE("IPv4 proto %d", ip->proto);
    /* Switch on packet protocol */
    switch (ip->proto)
    {
        /* ICMP Packet */
    case IPv4_PROTO_ICMP:
        icmpRecv(pkt);
        break;

        /* UDP Packet */
    case IPv4_PROTO_UDP:
#if NUDP
        udpRecv(pkt, &src, &dst);
#endif                          /* NUDP */
        break;

        /* TCP Packet */
    case IPv4_PROTO_TCP:
#if NTCP
        tcpRecv(pkt, &src, &dst);
#endif                          /* NTCP */
        break;

        /* Unknown IP packet protocol */
    default:
#if NRAW
        rawRecv(pkt, &src, &dst, ip->proto);
#endif                          /* NRAW */
        break;
    }

    return OK;
}