/*--------------------------------------------------------------------------
  Indicates buffer to WAN protocol.
  --------------------------------------------------------------------------*/
static void
ssh_wan_receive_buffer(SshNdisIMAdapter adapter, 
                       PUCHAR buffer, 
                       ULONG length)
{
  NDIS_STATUS status;

  NdisMWanIndicateReceive(&status, adapter->handle, adapter->wan_link_context,
                          buffer, length);

  if (status != NDIS_STATUS_SUCCESS)
    SSH_DEBUG(SSH_D_FAIL, ("WAN packet not accepted by protocol"));

  ssh_wan_free_buffer_receive(buffer);
}
void
ssh_wan_process_from_adapter(SshNdisIMAdapter adapter,
                             PUCHAR packet, 
                             ULONG packet_size,
                             PNDIS_STATUS status)
{
  PUCHAR decode_pos = packet;
  ULONG decode_len = packet_size;
  SshUInt32 protocol, flags;

  /* Get PPP header. */
  if (!ssh_wan_decode_ppp_header(&decode_pos, &decode_len, &protocol, &flags))
    {
      SSH_DEBUG(SSH_D_FAIL, ("Invalid PPP frame"));
      *status = NDIS_STATUS_FAILURE;
      return;
    }

  /* Reject compression/encryption negotiation. */
  if (protocol == SSH_PPP_PROTOCOL_CCP || protocol == SSH_PPP_PROTOCOL_ECP)
    {
      SSH_DEBUG(SSH_D_LOWSTART, ("Rejecting CCP/ECP"));
      ssh_wan_reject_protocol_receive(adapter, protocol,
                                      decode_pos, decode_len);
      *status = NDIS_STATUS_SUCCESS;
      return;
    }

  /* Reject IP-level compression/encryption. */
  if (protocol == SSH_PPP_PROTOCOL_IPCP4)
    {
      if (ssh_wan_intercept_ipcp_receive(adapter, decode_pos, decode_len))
        {
          SSH_DEBUG(SSH_D_LOWSTART, ("Intercepted IPCP frame"));
          *status = NDIS_STATUS_SUCCESS;
          return;
        }
    }

  SSH_DEBUG(SSH_D_LOWSTART, ("Passing PPP frame through"));

  /* Pass other protocols through. */
  NdisMWanIndicateReceive(status, adapter->handle,
                          adapter->wan_link_context,
                          packet, packet_size);
  return;
}
Esempio n. 3
0
VOID
IndicateRxToWrapper(
	MTL	*mtl
	)
{
	UCHAR	*BufferPtr;
	USHORT	BufferLength = 0;
	NDIS_STATUS	Status = NDIS_STATUS_SUCCESS;
	ADAPTER	*Adapter;
	MTL_AS	*as;
	MTL_RX_TBL	*RxTable;

	NdisAcquireSpinLock(&mtl->lock);

	Adapter = mtl->Adapter;
	RxTable = &mtl->rx_tbl;

	while (!IsRxIndicationFifoEmpty(mtl))
	{
		NdisAcquireSpinLock(&RxTable->lock);

		//
		// get the next completed rx assembly
		//
   		as = GetAssemblyFromRxIndicationFifo(mtl);

		if (!as)
		{
			D_LOG(D_ALWAYS, ("IndicateRx: Got a NULL as from queue! mtl: 0x%p", mtl));
			RxTable->IndicateReceiveError1++;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}


		//
		// if this is an old ras frame then we must strip off
		// the mac header Dst[6] + Src[6] + Length[2]
		//
		if (mtl->RecvFramingBits & RAS_FRAMING)
		{
			//
			// pass over the mac header - tommyd does not want to see this
			//
			BufferPtr = as->buf + 14;
	
			//
			// indicate with the size of the ethernet packet not the received size
			// this takes care of the old driver that does padding on small frames
			//
			BufferLength = as->buf[12];
			BufferLength = BufferLength << 8;
			BufferLength += as->buf[13];
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: RAS"));
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength));
		}
		else if (mtl->RecvFramingBits & PPP_FRAMING)
		{
			//
			// the received buffer is the data that needs to be inidcated
			//
			BufferPtr = as->buf;
	
			//
			// the received length is the length that needs to be indicated
			//
			BufferLength = as->len;
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: WrapperFrameType: PPP"));
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: BufPtr: 0x%p, BufLen: %d", BufferPtr, BufferLength));
		}
		else
		{
			//
			// unknown framing - what to do what to do
			// throw it away
			//
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, Unknown WrapperFramming: 0x%x", mtl, mtl->RecvFramingBits));
			RxTable->IndicateReceiveError2++;
			as->tot = 0;
			as->Queued = 0;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}
	
		if (BufferLength > MTL_MAC_MTU)
		{
			D_LOG(D_ALWAYS, ("IndicateRxToWrapper: mtl: 0x%p, ReceiveLength > MAX ALLOWED (1514):  RxLength: %d", mtl, as->len));
			RxTable->IndicateReceiveError3++;
			as->tot = 0;
			as->Queued = 0;
			NdisReleaseSpinLock(&RxTable->lock);
			goto exit_code;
		}

		//
		// send frame up
		//
		if (mtl->LinkHandle)
		{
			/* release assembly descriptor */
			NdisReleaseSpinLock(&RxTable->lock);

			NdisReleaseSpinLock(&mtl->lock);

			NdisMWanIndicateReceive(&Status,
									Adapter->Handle,
									mtl->LinkHandle,
									BufferPtr,
									BufferLength);

			NdisAcquireSpinLock(&mtl->lock);

			NdisAcquireSpinLock(&RxTable->lock);

			mtl->RecvCompleteScheduled = 1;
		}
	
	
		/* mark as free now */
		as->tot = 0;

		//
		// mark this guy as being free
		//
		as->Queued = 0;

		/* release assembly descriptor */
		NdisReleaseSpinLock(&RxTable->lock);
	}

	//
	// exit code
	// release spinlock and return
	//
    exit_code:

	NdisReleaseSpinLock(&mtl->lock);
}