/*++

*******************************************************************************
* Copyright (c) 1994-95 Digi International Inc., All Rights Reserved          *
*                                                                             *
* This  software  contains  proprietary  and  confidential   information   of *
* Digi International  Inc.   By  accepting  transfer  of this copy, Recipient *
* agrees to retain this software in  confidence,  to  prevent  disclosure  to *
* others,  and  to make no  use of this software other than that for which it *
* was delivered.  This is an unpublished copyright work  Digi   International *
* Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is *
* strictly prohibited.                                                        *
*                                                                             *
* Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc. *
* Confidential  when   combined   with   the   aggregated  modules  for  this *
* product) OBJECT CODE ONLY SOURCE MATERIALS                                  *
*                                                                             *
* (C) COPYRIGHT Digi International Inc. 1994-95                               *
*                                                                             *
* All Rights Reserved                                                         *
*                                                                             *
* US   Government   Users   Restricted   Rights   -   Use,   duplication   or *
* disclosure  restricted by GSA ADP Schedule Contract with Digi International *
* Inc.                                                                        *
*                                                                             *
*******************************************************************************

Module Name:

   utils.c

Abstract:

   This module contains general helper routines.

Author:

   Michael Zarns

Revision History:

   $Log: /Components/Windows/NT/Sync/Lan/UTILS.C $
 * 
 * 3     9/19/96 9:24a Mikez
 * Added X25 PVC support.
 * 
 * 2     8/13/96 10:48a Mikez
 * Fully abstracted Frame Relay code into three routines:  FrSend,
 * FrReceive and FrInit, and one AdapterObject field: RxControlLength.
 * This revision works and support Frame Relay only.
 * 
 * 1     8/05/96 2:14p Mikez
 * 
 * 1     3/11/96 3:16p Mikez
 * Revision 1.1  1995/08/23  07:48:02  mikez
 * Initial revision
 * 

--*/
#include "digilan.h"


BOOLEAN
DigiCompareMemory(
	PUCHAR pMem1, 
	PUCHAR pMem2, 
	ULONG Length
	)
/*++

Description:

	This routine is used to compare data at two locations in memory.  Returns
	TRUE or FALSE based on whether memory is identical or not, respectively.

Parameters:

	pMem1
		Address of first memory location to compare

	pMem2
		Address of second memory location to compare

	Length
		Count of bytes to compare

Return Value:

	TRUE if range of memory is identical, 
	otherwise FALSE

--*/
{
	while ( Length-- )																	\
		if ( *pMem1++ != *pMem2++ )													\
			return( FALSE );																\
																								\
	return( TRUE );																		\
}



PACKET_TYPE
DigiLanGetPacketType(
	IN PNDIS_PACKET pNdisPacket
	)
/*++

Description:

	Determines the type of packet, IP, IPX, or other.

Parameters:

	pNdisPacket
		The packet to be analyzed

--*/
{
	UCHAR MyHeader[ETHERNET_MAC_HEADER_SIZE+ETHERNET_LLC_HEADER_SIZE];
	NDIS_STATUS Status;

	Status = DigiGetNdisPacketData( (PVOID)MyHeader, 
	                                pNdisPacket,
	                                sizeof( MyHeader ),
											  0 );

	if ( !NT_SUCCESS( Status ) )
		return( PACKET_TYPE_UNKNOWN );

	if ( IsPacketIP( MyHeader ) )
		return( PACKET_TYPE_IP );
	
	if ( IsPacketIPX( MyHeader ) )
		return( PACKET_TYPE_IPX );
	
	if ( IsPacketARP( MyHeader ) )
		return( PACKET_TYPE_ARP );
	
	return( PACKET_TYPE_UNKNOWN );
}



NTSTATUS
DigiGetNdisPacketData( 
	OUT PUCHAR      pBuffer,
	IN PNDIS_PACKET pNdisPacket,
	IN ULONG        DataLength,
	IN ULONG        DataOffset
	)
/*++

Description:

	Copies data from the multiple ndis_buffers defined by pNdisPacket into a single
	contiguous buffer pData.  Starts the copy at offset DataOffset within the 
	ndis_packet, copying DataLength number of bytes.

Parameters:

	pBuffer
		Address of destination data buffer.

	pNdisPacket
		Address source ndis_packet.

	DataLength
		Number of bytes to copy.

	DataOffset
		Offset into ndis_packet data at which to start copying data.

Return Value:

	STATUS_SUCCESS, or some error.

--*/
{
	PNDIS_BUFFER pNdisBuffer;
	ULONG PacketLength;

	NdisQueryPacket( pNdisPacket, NULL, NULL, &pNdisBuffer, &PacketLength );

	ASSERT( pBuffer );
	ASSERT( DataLength + DataOffset <= PacketLength );

	if ( !pBuffer || DataLength + DataOffset > PacketLength )
		return( NDIS_STATUS_FAILURE );

	{
		ULONG SrcOffset      = DataOffset;
		ULONG DestOffset     = 0;
		ULONG BytesRemaining = DataLength;

		while ( pNdisBuffer && BytesRemaining )
		{
			PUCHAR pSrcBuffer;
			ULONG SrcLength;

			NdisQueryBuffer( pNdisBuffer, &pSrcBuffer, &SrcLength );
			if ( SrcLength <= SrcOffset )
				SrcOffset -= SrcLength;
			else
			{
				ULONG BytesToMove;

				if ( SrcOffset )
					SrcLength -= SrcOffset;
				
				BytesToMove = BytesRemaining < SrcLength ? BytesRemaining : SrcLength;
				NdisMoveMemory( pBuffer+DestOffset, pSrcBuffer+SrcOffset, BytesToMove );

				DestOffset     += BytesToMove;
				BytesRemaining -= BytesToMove;
				SrcOffset       = 0;
			}

			NdisGetNextBuffer( pNdisBuffer, &pNdisBuffer );
		}

		ASSERT( DestOffset == DataLength );
	}

	return( NDIS_STATUS_SUCCESS );
}
