Exemple #1
0
int main(int argc, char **argv)
{
	Sdr sdr;
	Object txExtent;
	Object txBundleZco;
	Object txNewBundle;
	BpDelivery rxDlv;
	int rxContentLength;
	ZcoReader rxReader;
	int rxLen;
	char rxContent[sizeof(testLine)];

	/* Start ION */
	ionstart_default_config("loopback-ltp/loopback.ionrc", 
			 NULL,
			 "loopback-ltp/loopback.ltprc",
			 "loopback-ltp/loopback.bprc",
			 "loopback-ltp/loopback.ipnrc",
			 NULL);

	/* Attach to ION */
	fail_unless(bp_attach() >= 0);
	sdr = bp_get_sdr();

	/* Send the loopback bundle */
	sdr_begin_xn(sdr);
	txExtent = sdr_malloc(sdr, sizeof(testLine) - 1);
	fail_unless(txExtent != 0);
	sdr_write(sdr, txExtent, testLine, sizeof(testLine) - 1);
	txBundleZco = zco_create(sdr, ZcoSdrSource, txExtent, 0, sizeof(testLine) - 1);
	fail_unless(sdr_end_xn(sdr) >= 0 && txBundleZco != 0);
	fail_unless(bp_send(NULL, testEid, NULL, 300, BP_STD_PRIORITY,
		NoCustodyRequested, 0, 0, NULL, txBundleZco, &txNewBundle) > 0);

	/* Receive the loopback bundle */
	fail_unless(bp_open(testEid, &rxSap) >= 0);
	fail_unless(bp_receive(rxSap, &rxDlv, IONTEST_DEFAULT_RECEIVE_WAIT) >= 0);
	fail_unless(rxDlv.result == BpPayloadPresent);
	sdr_begin_xn(sdr);
	rxContentLength = zco_source_data_length(sdr, rxDlv.adu);
	fail_unless(rxContentLength == sizeof(testLine) - 1);
	zco_start_receiving(rxDlv.adu, &rxReader);
	rxLen = zco_receive_source(sdr, &rxReader, rxContentLength, 
		rxContent);
	fail_unless(rxLen == rxContentLength);
	fail_unless(sdr_end_xn(sdr) >= 0);
	bp_release_delivery(&rxDlv, 1);
	bp_close(rxSap);

	/* Detach from ION */
	writeErrmsgMemos();
	bp_detach();

	/* Compare the received data */
	rxContent[sizeof(rxContent) - 1] = '\0';
	fail_unless(strncmp(rxContent, testLine, sizeof(testLine)) == 0);

	/* Stop ION */
	ionstop();

	CHECK_FINISH;
}
Exemple #2
0
static int	handleGreenSegment(AcqWorkArea *work, LtpSessionId *sessionId,
			unsigned char endOfBlock, unsigned int offset,
			unsigned int length, Object zco, unsigned int *buflen,				char **buffer)
{
	Sdr			sdr = getIonsdr();
	static LtpSessionId	currentSessionId = { 0, 0 };
	static unsigned int	currentOffset = 0;
	unsigned int		fillLength;
	ZcoReader		reader;
	int			result;

	if (zco == 0)		/*	Import session canceled.	*/
	{
		bpCancelAcq(work);
		currentSessionId.sourceEngineId = 0;
		currentSessionId.sessionNbr = 0;
		currentOffset = 0;
		return 0;
	}

	if (zco_source_data_length(sdr, zco) != length)
	{
		return 0;	/*	Just discard the segment.	*/
	}

	if (sessionId->sourceEngineId != currentSessionId.sourceEngineId
	|| sessionId->sessionNbr != currentSessionId.sessionNbr)
	{
		/*	Did not receive end-of-block segment for the
		 *	block that was being received.  Discard the
		 *	partially received bundle in the work area,
		 *	if any.						*/

		bpCancelAcq(work);
		currentSessionId.sourceEngineId = 0;
		currentSessionId.sessionNbr = 0;
		currentOffset = 0;
	}

	if (currentOffset == 0)
	{
		/*	Start new green bundle acquisition.		*/

		if (bpBeginAcq(work, 0, NULL) < 0)
		{
			putErrmsg("Can't begin acquisition of bundle.", NULL);
			return -1;
		}

		currentSessionId.sourceEngineId = sessionId->sourceEngineId;
		currentSessionId.sessionNbr = sessionId->sessionNbr;
	}

	if (offset < currentOffset)	/*	Out of order.		*/
	{
		return 0;	/*	Just discard the segment.	*/
	}

	if (offset > currentOffset)
	{
		/*	Convergence layer must not deliver incomplete
		 *	bundles to BP.  Practically speaking, this
		 *	gap in segment sequence must be treated as
		 *	malformation of the bundle.			*/

		work->malformed = 1;

		/*	But continue bundle acquisition anyway, in
		 *	case the incomplete bundle is useful for some
		 *	diagnostic purpose.				*/

		fillLength = offset - currentOffset;
		if (fillLength > *buflen)
		{
			/*	Make buffer big enough for the fill
			 *	data.					*/

			if (*buffer)
			{
				MRELEASE(*buffer);
				*buflen = 0;
			}

			*buffer = MTAKE(fillLength);
			if (*buffer == NULL)
			{
				/*	Gap is too large to fill.
				 *	Might be a DOS attack; cancel
				 *	acquisition.			*/

				bpCancelAcq(work);
				currentSessionId.sourceEngineId = 0;
				currentSessionId.sessionNbr = 0;
				currentOffset = 0;
				return 0;
			}

			*buflen = fillLength;
		}

		memset(*buffer, 0, fillLength);
		if (bpContinueAcq(work, *buffer, (int) fillLength, 0) < 0)
		{
			putErrmsg("Can't insert bundle fill data.", NULL);
			return -1;
		}

		currentOffset += fillLength;
	}

	if (length > *buflen)
	{
		/*	Make buffer big enough for the green data.	*/

		if (*buffer)
		{
			MRELEASE(*buffer);
			*buflen = 0;
		}

		*buffer = MTAKE(length);
		if (*buffer == NULL)
		{
			/*	Segment is too large.  Might be a
			 *	DOS attack; cancel acquisition.		*/

			bpCancelAcq(work);
			currentSessionId.sourceEngineId = 0;
			currentSessionId.sessionNbr = 0;
			currentOffset = 0;
			return 0;
		}

		*buflen = length;
	}

	/*	Extract data from segment ZCO so that it can be
	 *	appended to the bundle acquisition ZCO.  Note
	 *	that we're breaking the "zero-copy" model here;
	 *	it would be better to have an alternate version
	 *	of bpContinueAcq that uses zco_clone_source_data
	 *	to append the segment ZCO's source data to the
	 *	acquisition ZCO in the work area. (TODO)		*/

	zco_start_receiving(zco, &reader);
	CHKERR(sdr_begin_xn(sdr));
	result = zco_receive_source(sdr, &reader, length, *buffer);
	if (sdr_end_xn(sdr) < 0 || result < 0)
	{
		putErrmsg("Failed reading green segment data.", NULL);
		return -1;
	}

	if (bpContinueAcq(work, *buffer, (int) length, 0) < 0)
	{
		putErrmsg("Can't continue bundle acquisition.", NULL);
		return -1;
	}

	currentOffset += length;
	if (endOfBlock)
	{
		if (bpEndAcq(work) < 0)
		{
			putErrmsg("Can't end acquisition of bundle.", NULL);
			return -1;
		}

		currentSessionId.sourceEngineId = 0;
		currentSessionId.sessionNbr = 0;
		currentOffset = 0;
	}

	return 0;
}
Exemple #3
0
static void	*getBundles(void *parm)
{
	RxThreadParms		*parms = (RxThreadParms *) parm;
	char			ownEid[64];
	Sdr			sdr = getIonsdr();
	BpDelivery		dlv;
	uvast			profNum;
	Scalar			seqNum;
	char			type;
	unsigned int		aduLength;
	int			bytesRemaining;
	ZcoReader		reader;
	unsigned char		*buffer;
	int			bytesToRead;
	int			sdnvLength;
	unsigned char		*cursor;

	isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%d",
			getOwnNodeNbr(), DTPC_RECV_SVC_NBR);
	if (bp_open(ownEid, &(parms->rxSap)) < 0)
	{
		putErrmsg("DTPC can't open own 'recv' endpoint.", ownEid);
		parms->running = 0;
		return NULL;
	}

	writeMemo("[i] dtpcd receiver thread has started.");
	while (parms->running)
	{
		if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0)
		{
			putErrmsg("dtpcd bundle reception failed.", NULL);
			parms->running = 0;
			continue;
		}

		switch (dlv.result)
		{
		case BpEndpointStopped:
			parms->running = 0;
			break;

		case BpPayloadPresent:
			CHKNULL(sdr_begin_xn(sdr));

			/* Since the max length of a Sdnv is 10 bytes,
			 * read 21 bytes to be sure that the Profile
			 * and Sequence number Sdnvs plus the type
			 * were read.					*/

			aduLength = zco_source_data_length(sdr, dlv.adu);
			bytesRemaining = aduLength;
			if (aduLength < 21)	/* Just in case we receive
						 * a very small adu.	*/
			{			
				bytesToRead = aduLength;
			}
			else
			{
				bytesToRead = 21;
			}

			buffer = MTAKE(bytesToRead);
			if (buffer == NULL)
			{
				putErrmsg("Out of memory.",NULL);
				return NULL;
			}

			cursor = buffer;
			zco_start_receiving(dlv.adu, &reader);
			if (zco_receive_headers(sdr, &reader, bytesToRead,
					(char *) buffer) < 0)
			{
				putErrmsg("dtpcd can't receive ADU header.",
						itoa(bytesToRead));
				sdr_cancel_xn(sdr);
				MRELEASE(buffer);
				parms->running = 0;
				continue;
			}

			type = *cursor;		/* Get the type byte.	*/
			cursor++;
			bytesRemaining--;
			sdnvLength = decodeSdnv(&profNum, cursor);
			cursor += sdnvLength;
			bytesRemaining -= sdnvLength;
			sdnvLength = sdnvToScalar(&seqNum, cursor);
			cursor += sdnvLength;
			bytesRemaining -= sdnvLength;

			/*	Mark remaining bytes as source data.	*/

			zco_delimit_source(sdr, dlv.adu, cursor - buffer,
					bytesRemaining);
			zco_strip(sdr, dlv.adu);
			MRELEASE(buffer);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("dtpcd can't handle bundle delivery.",
						NULL);
				parms->running = 0;
				continue;
			}

			switch (type)
			{
			case 0x00:	/*	Received an adu.	*/
				switch (handleInAdu(sdr, &dlv, profNum, seqNum))
				{
				case -1:
					putErrmsg("dtpcd can't handle inbound \
adu.", NULL);
					parms->running = 0;
					continue;

				case 1:
					if (parseInAdus(sdr) < 0)
					{
						putErrmsg("dtpcd can't parse \
							inbound adus.", NULL);
						parms->running = 0;
						continue;
					}

				case 0: 
					/* 	Intentional fall-through to 
					 *	next case. 		*/				
				default:
					if (dlv.ackRequested)
					{
						if (sendAck(parms->txSap,
								profNum, seqNum,
								&dlv) < 0)
						{
							putErrmsg("dtpcd can't \
send ack.", NULL);
							parms->running = 0;
							continue;
						}
					} 
					break;
				}

				break;

			case 0x01:	/*	Received an ACK.	*/
				if (handleAck(sdr, &dlv, profNum, seqNum) < 0)
				{
					putErrmsg("dtpcd can't handle ACK.",
							NULL);
					parms->running = 0;
					continue;
				}

				break;
			default:
				writeMemo("[?] Invalid item type. Corrupted \
item?");
				break;
			}

		default:
			break;
		}
Exemple #4
0
static void	*receivePdus(void *parm)
{
    RxThreadParms	*parms = (RxThreadParms *) parm;
    char		ownEid[64];
    Sdr		sdr;
    BpDelivery	dlv;
    int		contentLength;
    ZcoReader	reader;
    unsigned char	*buffer;

    buffer = MTAKE(CFDP_MAX_PDU_SIZE);
    if (buffer == NULL)
    {
        putErrmsg("bputa receiver thread can't get buffer.", NULL);
        parms->running = 0;
        return NULL;
    }

    isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%u",
             getOwnNodeNbr(), CFDP_RECV_SVC_NBR);
    if (bp_open(ownEid, &(parms->rxSap)) < 0)
    {
        MRELEASE(buffer);
        putErrmsg("CFDP can't open own 'recv' endpoint.", ownEid);
        parms->running = 0;
        return NULL;
    }

    sdr = bp_get_sdr();
    writeMemo("[i] bputa input has started.");
    while (parms->running)
    {
        if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0)
        {
            putErrmsg("bputa bundle reception failed.", NULL);
            parms->running = 0;
            continue;
        }

        switch (dlv.result)
        {
        case BpEndpointStopped:
            parms->running = 0;
            break;

        case BpPayloadPresent:
            contentLength = zco_source_data_length(sdr, dlv.adu);
            CHKNULL(sdr_begin_xn(sdr));
            zco_start_receiving(dlv.adu, &reader);
            if (zco_receive_source(sdr, &reader, contentLength,
                                   (char *) buffer) < 0)
            {
                sdr_cancel_xn(sdr);
                putErrmsg("bputa can't receive bundle ADU.",
                          itoa(contentLength));
                parms->running = 0;
                continue;
            }

            if (sdr_end_xn(sdr) < 0)
            {
                putErrmsg("bputa can't handle bundle delivery.",
                          NULL);
                parms->running = 0;
                continue;
            }

            if (cfdpHandleInboundPdu(buffer, contentLength) < 0)
            {
                putErrmsg("bputa can't handle inbound PDU.",
                          NULL);
                parms->running = 0;
            }

            break;

        default:
            break;
        }

        bp_release_delivery(&dlv, 1);

        /*	Make sure other tasks have a chance to run.	*/

        sm_TaskYield();
    }

    bp_close(parms->rxSap);
    MRELEASE(buffer);
    writeMemo("[i] bputa input has stopped.");
    return NULL;
}
Exemple #5
0
static int	processCmdFile(Sdr sdr, BpDelivery *dlv)
{
	int		contentLength;
	ZcoReader	reader;
	int		len;
	char		*content;
	char		*endOfContent;
	char		*line;
	char		*delimiter;
	char		*nextLine;
	int		lineLength;
	char		*fileName = NULL;
	int		opsFile = -1;

	contentLength = zco_source_data_length(sdr, dlv->adu);
	if (contentLength > 64000)
	{
		putErrmsg("lgagent: bundle content length > 64000, ignored.",
				itoa(contentLength));
		return 0;
	}

	content = MTAKE(contentLength + 1);
	if (content == NULL)
	{
		putErrmsg("lgagent: no space for bundle content.", NULL);
		return -1;
	}

	zco_start_receiving(dlv->adu, &reader);
	CHKERR(sdr_begin_xn(sdr));
	len = zco_receive_source(sdr, &reader, contentLength, content);
	if (sdr_end_xn(sdr) < 0)
	{
		return -1;
	}

	if (len < 0)
	{
		MRELEASE(content);
		putErrmsg("lgagent: can't receive bundle content.", NULL);
		return -1;
	}

	endOfContent = content + contentLength;
	*endOfContent = 0;
	line = content;
	while (line < endOfContent)
	{
		delimiter = strchr(line, '\n');	/*	LF (newline)	*/
		if (delimiter == NULL)		/*	No LF or CRLF	*/
		{
			writeMemoNote("[?] lgagent: non-terminated line, \
discarding bundle content", content);
			closeOpsFile(&opsFile);
			fileName = NULL;
			break;			/*	Out of loop.	*/
		}

		nextLine = delimiter + 1;
		lineLength = nextLine - line;
		*delimiter = 0;		/*	Strip off the LF.	*/
		if (lineLength == 1)	/*	Empty line.		*/
		{
			line = nextLine;
			continue;
		}

		/*	Case 1: line is start of an operations file.	*/

		if (*line == '[')	/*	Start loading file.	*/
		{
			if (fileName)
			{
				putErrmsg("lgagent: '[' line before end of \
load, no further activity.", itoa(line - content));
				closeOpsFile(&opsFile);
				fileName = NULL;
				break;		/*	Out of loop.	*/
			}

			/*	Remainder of line is file name.		*/

			fileName = line + 1;
			opsFile = iopen(fileName, O_RDWR | O_CREAT, 0777);
			if (opsFile < 0)
			{
				putSysErrmsg("lgagent: can't open operations \
file name, no further activity", fileName);
				fileName = NULL;
				break;		/*	Out of loop.	*/
			}

#ifdef TargetFFS
			closeOpsFile(&opsFile);
#endif
			line = nextLine;
			continue;
		}