/*-------------------------------------------------------------------------- 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; }
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); }