Beispiel #1
0
/**
 * @ingroup raw
 *
 * Write a packet to a raw socket.
 * @param devptr pointer to RAW device
 * @param buf buffer to write
 * @param len size of the buffer 
 * @return number of octets written, SYSERR if error occurred 
 */
devcall rawWrite(device *devptr, void *buf, uint len)
{
    struct raw *rawptr;

    rawptr = &rawtab[devptr->minor];
    return rawSend(rawptr, buf, len);
}
Beispiel #2
0
// Send a new packet, this is what user code should call
void Net::send(uint8_t len, bool ack) {
#ifndef NET_NONE
  //uint8_t hdr = RF12_HDR_DST | (ack ? RF12_HDR_ACK : 0) | NET_GW_NODE;
  uint8_t hdr = (ack ? RF12_HDR_ACK : 0) | node_id;
  rawSend(len, hdr);
#endif
}
Beispiel #3
0
bool
LLHeartbeat::send(F32 timeout_sec)
{
	bool total_success = false;
	int result = 1;

	if (timeout_sec > 0.f) {
		// force a spin until success or timeout
		result = rawSendWithTimeout(timeout_sec);
	} else {
		if (mBeatTimer.hasExpired()) {
			// zero-timeout; we don't care too much whether our
			// heartbeat was digested.
			result = rawSend();
			//LL_INFOS() << " HEARTSENDb=" << result << LL_ENDL;
		}
	}

	if (result == -1) {
		// big failure.
	} else if (result == 0) {
		total_success = true;
	} else {
		// need to retry at some point
	}

	if (total_success) {
		mBeatTimer.reset();
		mBeatTimer.setTimerExpirySec(mSecsBetweenHeartbeat);
		// reset the time until we start panicking about lost
		// heartbeats again.
		mPanicTimer.reset();
		mPanicTimer.setTimerExpirySec(mAggressiveHeartbeatPanicSecs);
	} else {
		// leave mBeatTimer as expired so we'll lazily poke the
		// watchdog again next time through.
	}

	if (mPanicTimer.hasExpired()) {
		// It's been ages since we successfully had a heartbeat
		// digested by the watchdog.  Sit here and spin a while
		// in the hope that we can force it through.
		LL_WARNS() << "Unable to deliver heartbeat to launcher for " << mPanicTimer.getElapsedTimeF32() << " seconds.  Going to try very hard for up to " << mAggressiveHeartbeatMaxBlockingSecs << " seconds." << LL_ENDL;
		result = rawSendWithTimeout(mAggressiveHeartbeatMaxBlockingSecs);
		if (result == 0) {
			total_success = true;
		} else {
			// we couldn't even force it through.  That's bad,
			// but we'll try again in a while.
			LL_WARNS() << "Could not deliver heartbeat to launcher even after trying very hard for " << mAggressiveHeartbeatMaxBlockingSecs << " seconds." << LL_ENDL;
		}
		
		// in any case, reset the panic timer.
		mPanicTimer.reset();
		mPanicTimer.setTimerExpirySec(mAggressiveHeartbeatPanicSecs);
	}

	return total_success;
}
Beispiel #4
0
void ASIOSocketWrapper::sendProtocolHeader(const MultiplexedSocketPtr&parentMultiSocket, const Address& address,  const UUID&value, unsigned int numConnections) {
//    if (paerntMultiSocket->isZeroDelim()) {
    std::stringstream header;
    header << "GET /" << value.toString() << " HTTP/1.1\r\n";
    header << "Upgrade: WebSocket\r\n";
    header << "Connection: Upgrade\r\n";

    std::string hostname=address.getHostName();
    for (std::string::iterator hi=hostname.begin(),he=hostname.end(); hi!=he; ++hi) {
        *hi=std::tolower(*hi);
    }
    header << "Host: " << hostname;
    if (address.getService()!="80")
        header << ":" << address.getService();
    header << "\r\n";

    header << "Origin: " << address.getHostName() << "\r\n";

    if (parentMultiSocket->getStreamType()!= TCPStream::RFC_6455) {
        header << "Sec-WebSocket-Key1: x!|6 j9  U 1 guf  36Y04  |   4\r\n";
        header << "Sec-WebSocket-Key2: 3   59   2 E4   _11  x80      \r\n";
    } else {
        header << "Sec-WebSocket-Version: 13\r\n";
        header << "Sec-WebSocket-Key: MTIzNDU2Nzg5MGFiY2RlZg==\r\n";
    }
    header << "Sec-WebSocket-Protocol: "
           << (parentMultiSocket->getStreamType()==TCPStream::BASE64_ZERODELIM?"wssst":"sst")
           << numConnections << "\r\n";
    header << "\r\n";
    if (parentMultiSocket->getStreamType()!= TCPStream::RFC_6455) {
        header << "abcdefgh";
    }

    std::string finalHeader(header.str());
    Chunk * headerData= new Chunk(finalHeader.begin(),finalHeader.end());
    rawSend(parentMultiSocket,headerData,true);
    /*
        }else {
            UUID return_value=(parentMultiSocket->isZeroDelim()?massageUUID(UUID::random()):UUID::random());

            Chunk *headerData=new Chunk(TCPStream::TcpSstHeaderSize);
            copyHeader(&*headerData->begin(),parentMultiSocket->isZeroDelim()?TCPStream::WEBSOCKET_STRING_PREFIX():TCPStream::STRING_PREFIX(),value,numConnections);
            rawSend(parentMultiSocket,headerData,true);
        }
    */
}
Beispiel #5
0
int
LLHeartbeat::rawSendWithTimeout(F32 timeout_sec)
{
	int result = 0;

	// Spin tightly until our heartbeat is digested by the watchdog
	// or we time-out.  We don't really want to sleep because our
	// wake-up time might be undesirably synchronised to a hidden
	// clock by the system's scheduler.
	mTimeoutTimer.reset();
	mTimeoutTimer.setTimerExpirySec(timeout_sec);
	do {
		result = rawSend();
		//LL_INFOS() << " HEARTSENDc=" << result << LL_ENDL;
	} while (result==1 && !mTimeoutTimer.hasExpired());

	return result;
}
Beispiel #6
0
void ASIOSocketWrapper::sendServerProtocolHeader(const MultiplexedSocketPtr& thus, const std::string&origin, const std::string&host, const std::string&port, const std::string&resource_name, const std::string&subprotocol, const std::string& response) {
    std::stringstream header;
    header << "HTTP/1.1 101 Web Socket Protocol Handshake\r\n";
    header << "Upgrade: WebSocket\r\n";
    header << "Connection: Upgrade\r\n";
    if (thus->getStreamType() == TCPStream::RFC_6455) {
        header << "Access-Control-Allow-Origin: " << origin << "\r\n";
        header << "Location: ws://" << host << resource_name << "\r\n";
        header << "Sec-WebSocket-Accept: " << response << "\r\n";
        header << "Sec-WebSocket-Protocol: " << subprotocol << "\r\n";
        header << "\r\n";
    } else {
        header << "Sec-WebSocket-Origin: " << origin << "\r\n";
        header << "Sec-WebSocket-Location: ws://" << host << resource_name << "\r\n";
        header << "WebSocket-Protocol: " << subprotocol << "\r\n";
        header << "\r\n";
        header << response;
    }

    std::string finalHeader(header.str());
    Chunk * headerData= new Chunk(finalHeader.begin(),finalHeader.end());
    rawSend(thus,headerData,true);
}
Beispiel #7
0
bool SgsClient::talk(const std::string &msg)
{
    if (msg.empty() || msg.size() > 500)
        return false;
    uLong len = compressBound(msg.size());
    char *dt = new char[len + 6];
    compress((Bytef*)dt + 6, &len, (Bytef*)msg.c_str(), msg.length());
    if (len > SGS_MAX_TALK_LEN) {
        delete dt;
        return false;
    }
    writeToBuffer(dt + 5, (uint8_t)len);
    uint8_t clen = msg.size() / 2;
    if ((msg.size() & 1) == 1)//不能被2整除
        clen++;
    writeToBuffer(dt + 4, clen);
    uint16_t slen = (uint16_t)len + 2;
    writeToBuffer(dt + 2, slen);
    slen = Command_Talk;
    writeToBuffer(dt, slen);
    rawSend(dt, len + 6);
    return true;
}
 /**
  *  Sends a streamID #0 packet with further control data on it.
  *  To start with only stream disconnect and the ack thereof are allowed
  */
 void sendControlPacket(const MultiplexedSocketPtr&parentMultiSocket, TCPStream::TCPStreamControlCodes code,const Stream::StreamID&sid) {
     rawSend(parentMultiSocket,constructControlPacket(code,sid),true);
 }
Beispiel #9
0
/**
 * Tests raw sockets.
 * @return OK when testing is complete
 */
thread test_raw(bool verbose)
{
#if RAW0
    /* the failif macro depends on 'passed' and 'verbose' vars */
    bool passed = TRUE;
    device *devptr;
    struct raw *rawptr;
    struct netif *netptr;
    struct netaddr lip;
    struct netaddr rip;
    struct netaddr mask;
    struct packet *pkt;
    struct packet *pktA;
    struct pcap_pkthdr phdr;
    struct pcap_file_header pcap;
    uchar *data;
    uchar buf[500];
    int nproc;
    int wait;
    int i;

    lip.type = NETADDR_IPv4;
    lip.len = IPv4_ADDR_LEN;
    lip.addr[0] = 192;
    lip.addr[1] = 168;
    lip.addr[2] = 1;
    lip.addr[3] = 6;

    rip.type = NETADDR_IPv4;
    rip.len = IPv4_ADDR_LEN;
    rip.addr[0] = 192;
    rip.addr[1] = 168;
    rip.addr[2] = 1;
    rip.addr[3] = 1;

    mask.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;
    mask.addr[0] = 255;
    mask.addr[1] = 255;
    mask.addr[2] = 255;
    mask.addr[3] = 0;

    /* Initialization */
    testPrint(verbose, "Test case initialization");
    data = (uchar *)(&_binary_data_testraw_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "");
    }
    else
    {
        if (SYSERR == netUp(ELOOP, &lip, &mask, NULL))
        {
            close(ELOOP);
            failif(TRUE, "");
        }
        else
        {
            netptr = NULL;
            for (i = 0; i < NNETIF; i++)
            {
                if (ELOOP == netiftab[i].dev)
                {
                    netptr = &netiftab[i];
                    break;
                }
            }
            pkt = netGetbuf();
            failif(((NULL == netptr) || (SYSERR == (int)pkt)), "");
        }
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Proto Only)");
    rawptr = NULL;
    if (SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (rawptr->localip.type != NULL)
                || (rawptr->remoteip.type != NULL)
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    testPrint(verbose, "Open RAW (Already Open)");
    failif((SYSERR != open(RAW0, NULL, NULL, IPv4_PROTO_ICMP)),
           "Double open() succeeded");

    /* Test Control */
    testPrint(verbose, "Control (Closed Socket)");
    failif((control(RAW1, RAW_CTRL_SETFLAG, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Bad Params)");
    failif((control(RAW0, -1, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Set Flag)");
    failif(((NULL != control(RAW0, RAW_CTRL_SETFLAG,
                             (RAW_IACCEPT | RAW_IHDR), NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (0 == (rawptr->flags & RAW_IHDR))), "");

    testPrint(verbose, "Control (Clear Flag)");
    failif(((RAW_IHDR != control(RAW0, RAW_CTRL_CLRFLAG,
                                 RAW_IHDR, NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (1 == (rawptr->flags & RAW_IHDR))), "");

    /* Test Close */
    testPrint(verbose, "Close RAW");
    if (SYSERR == close(RAW0))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_FREE)
                || (rawptr->dev != NULL)), "Control block not clear");
    }

    testPrint(verbose, "Close RAW (Already Closed)");
    failif((SYSERR != close(RAW0)), "Did not SYSERR");

    /* Test demux */
    testPrint(verbose, "Demulitplexing (No sockets)");
    failif((NULL != rawDemux(&rip, &lip, IPv4_PROTO_ICMP)), "");

    testPrint(verbose, "Demulitplexing (All Protos)");
    if ((SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_IGMP))
        || (SYSERR == open(RAW1, NULL, NULL, NULL)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Proto)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, NULL, IPv4_PROTO_IGMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Remote IP)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Local IP)");
    if ((SYSERR == open(RAW0, NULL, &rip, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, &lip, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Full Spec)");
    if (SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (FALSE == netaddrequal(&lip, &rawptr->localip))
                || (FALSE == netaddrequal(&rip, &rawptr->remoteip))
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    /* Test receive */
    testPrint(verbose, "Receive (Bad Params)");
    /* Get 1st packet */
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt->len = phdr.caplen;
    memcpy(pkt->data, data, phdr.caplen);
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    failif(((SYSERR != rawRecv(NULL, NULL, NULL, NULL))
            || (SYSERR != rawRecv(pkt, &rip, NULL, NULL))), "");

    testPrint(verbose, "Receive (No Match)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_IGMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->icount != 0)
                || (semcount(rawptr->isema) != 0)
                || (TRUE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] == pktA)), "Packet enqueued");

    }

    testPrint(verbose, "Receive (One Pkt)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->istart != 0)
                || (rawptr->icount != 1)
                || (semcount(rawptr->isema) != 1)
                || (FALSE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] != pktA)), "Incorrectly enqueued");
    }

    testPrint(verbose, "Read (Closed socket)");
    failif((SYSERR != read(RAW1, buf, 500)), "");

    testPrint(verbose, "Read (One Pkt)");
    failif(((read(RAW0, buf, 500) != 8)
            || (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 8)
                != 0)
            || (rawptr->icount != 0)
            || (rawptr->istart != 1)
            || (semcount(rawptr->isema) != 0)
            || (rawptr->in[0] != NULL)), "");

    testPrint(verbose, "Read (Include header)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IHDR;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != (IPv4_HDR_LEN + 8))
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN), IPv4_HDR_LEN + 8)
                 != 0) || (rawptr->icount != 0) || (rawptr->istart != 2)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->in[0] != NULL)), "");
    }


    testPrint(verbose, "Read (Accept)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IACCEPT;
    rawptr->remoteip.type = NULL;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != 8)
                || (FALSE == netaddrequal(&rawptr->remoteip, &rip))), "");
    }

    testPrint(verbose, "Read (Small buf)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 2) != 2)
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 2)
                 != 0)), "");
    }

    testPrint(verbose, "Receive (Full buf)");
    for (i = 0; i < RAW_IBLEN; i++)
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
        {
            break;
        }
    }
    if (i < RAW_IBLEN)
    {
        failif(TRUE, "Unable to fill buffer");
    }
    else
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        failif((SYSERR != rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP)),
               "Did not return SYSERR");
    }

    testPrint(verbose, "Close RAW");
    failif((SYSERR == close(RAW0)), "");

    /* Test Write/Send */
    testPrint(verbose, "Open RAW");
    if (SYSERR == open(RAW0, &lip, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(FALSE, "");
    }

    testPrint(verbose, "Send (Bad Params)");
    failif((rawSend(NULL, NULL, 0) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec)");
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec Hdr Inc)");
    rawptr->flags = RAW_OHDR;
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Net Hdr Included)");
    /* Add ARP entry */
    /* Get 2nd Packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Get 3rd Packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    memcpy(pkt->data, data, phdr.caplen);
    pkt->len = phdr.caplen;
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    /* Wait for ARP entry to be added */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(MAX_WAIT, "ARP entry failed");
    }
    else
    {
        netaddrcpy(&rawptr->remoteip, &rip);
        control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
        if (SYSERR == rawSend(rawptr, pkt->nethdr, IPv4_HDR_LEN + 8))
        {
            failif(TRUE, "Returned SYSERR");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
            failif((memcmp(pkt->data, buf, pkt->len) != 0),
                   "Incorrect Packet");
        }
    }

    testPrint(verbose, "Send");
    rawptr->flags = NULL;
    netaddrcpy(&rawptr->remoteip, &rip);
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == rawSend(rawptr, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    testPrint(verbose, "Write");
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == write(RAW0, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    close(RAW0);
    netDown(ELOOP);
    close(ELOOP);

    /* always print out the overall tests status */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }
#endif                          /* RAW0 */
    return OK;
}