static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) { struct sk_buff *skb; struct cdc_mbim_state *info = (void *)&dev->data; struct cdc_ncm_ctx *ctx = info->ctx; int len; int nframes; int x; int offset; struct usb_cdc_ncm_ndp16 *ndp16; struct usb_cdc_ncm_dpe16 *dpe16; int ndpoffset; int loopcount = 50; /* arbitrary max preventing infinite loop */ u8 *c; u16 tci; ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); if (ndpoffset < 0) goto error; next_ndp: nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); if (nframes < 0) goto error; ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); switch (ndp16->dwSignature & cpu_to_le32(0x00ffffff)) { case cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN): c = (u8 *)&ndp16->dwSignature; tci = c[3]; break; case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN): c = (u8 *)&ndp16->dwSignature; tci = c[3] + 256; break; default: netif_dbg(dev, rx_err, dev->net, "unsupported NDP signature <0x%08x>\n", le32_to_cpu(ndp16->dwSignature)); goto err_ndp; } dpe16 = ndp16->dpe16; for (x = 0; x < nframes; x++, dpe16++) { offset = le16_to_cpu(dpe16->wDatagramIndex); len = le16_to_cpu(dpe16->wDatagramLength); /* * CDC NCM ch. 3.7 * All entries after first NULL entry are to be ignored */ if ((offset == 0) || (len == 0)) { if (!x) goto err_ndp; /* empty NTB */ break; } /* sanity checking */ if (((offset + len) > skb_in->len) || (len > ctx->rx_max)) { netif_dbg(dev, rx_err, dev->net, "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", x, offset, len, skb_in); if (!x) goto err_ndp; break; } else { skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len, tci); if (!skb) goto error; usbnet_skb_return(dev, skb); } } err_ndp: /* are there more NDPs to process? */ ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); if (ndpoffset && loopcount--) goto next_ndp; return 1; error: return 0; }
static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) { struct sk_buff *skb; struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; int len; int nframes; int x; int offset; struct usb_cdc_ncm_ndp16 *ndp16; struct usb_cdc_ncm_dpe16 *dpe16; int ndpoffset; int loopcount = 50; /* arbitrary max preventing infinite loop */ ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); if (ndpoffset < 0) goto error; next_ndp: nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); if (nframes < 0) goto error; ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); if (le32_to_cpu(ndp16->dwSignature) != USB_CDC_NCM_NDP16_NOCRC_SIGN) { pr_debug("invalid DPT16 signature <%u>\n", le32_to_cpu(ndp16->dwSignature)); goto err_ndp; } dpe16 = ndp16->dpe16; for (x = 0; x < nframes; x++, dpe16++) { offset = le16_to_cpu(dpe16->wDatagramIndex); len = le16_to_cpu(dpe16->wDatagramLength); /* * CDC NCM ch. 3.7 * All entries after first NULL entry are to be ignored */ if ((offset == 0) || (len == 0)) { if (!x) goto err_ndp; /* empty NTB */ break; } /* sanity checking */ if (((offset + len) > skb_in->len) || (len > ctx->rx_max) || (len < ETH_HLEN)) { pr_debug("invalid frame detected (ignored)" "offset[%u]=%u, length=%u, skb=%p\n", x, offset, len, skb_in); if (!x) goto err_ndp; break; } else { skb = skb_clone(skb_in, GFP_ATOMIC); if (!skb) goto error; skb->len = len; skb->data = ((u8 *)skb_in->data) + offset; skb_set_tail_pointer(skb, len); usbnet_skb_return(dev, skb); } } err_ndp: /* are there more NDPs to process? */ ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); if (ndpoffset && loopcount--) goto next_ndp; return 1; error: return 0; }
BOOLEAN cdc_ncm_rx_fixup(PMP_ADAPTER Adapter, PRCB prcb) { NTSTATUS NtStatus=STATUS_SUCCESS; PMP_USBPIPE usbpipe=Adapter->UsbPipeForNIC; NCMDWORD len; int nframes; int x; int offset; PUSB_CDC_NCM_NDP16 ndp16; PUSB_CDC_NCM_DPE16 dpe16; int ndpoffset,ndeoffset; int currentFrame; int indexArray=0; int loopcount = 50; /* arbitrary max preventing infinite loop */ if(prcb->bIsOver) return TRUE; ndpoffset=prcb->nextndpoffset; ndeoffset=prcb->nextndeoffset; if (0==ndpoffset) { NtStatus=cdc_ncm_rx_verify_nth16(Adapter, prcb,&ndpoffset); if (!NT_SUCCESS(NtStatus)) goto error; } next_ndp: NtStatus = cdc_ncm_rx_verify_ndp16(prcb, ndpoffset,&nframes); if (!NT_SUCCESS(NtStatus)) goto error; ndp16 = (PUSB_CDC_NCM_NDP16)(prcb->pDataForNTB + ndpoffset); if (ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { DEBUGP(MP_ERROR,("invalid DPT16 signature <%#010x>\n",le32_to_cpu(ndp16->dwSignature)) ); goto err_ndp; } if(0==ndeoffset) dpe16 = ndp16->dpe16; else dpe16=(PUSB_CDC_NCM_DPE16)((PUCHAR)ndp16+ndeoffset); currentFrame=(int)((dpe16-ndp16->dpe16)/sizeof(USB_CDC_NCM_DPE16)); for (x = currentFrame; x < nframes; x++, dpe16++) { offset = le16_to_cpu(dpe16->wDatagramIndex); len = le16_to_cpu(dpe16->wDatagramLength); /* * CDC NCM ch. 3.7 * All entries after first NULL entry are to be ignored */ if ((offset == 0) || (len == 0)) { if (!x) goto err_ndp; /* empty NTB */ break; } /* sanity checking */ if (((offset + len) > prcb->ulSize) || (len > usbpipe->rx_max) || (len < ETH_HEADER_SIZE)) { DEBUGP(MP_ERROR,("invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", x, offset, len, prcb) ); if (!x) goto err_ndp; break; } else { if(indexArray>=RCB_BUFFERARRAY_SIZE) { prcb->nextndpoffset=ndpoffset; prcb->nextndeoffset=(NCMDWORD)((PUCHAR)dpe16-(PUCHAR)ndp16); return FALSE; } else{ NICIndicateReceivedPacket(prcb,offset,len,indexArray); Adapter->GoodReceives++; indexArray++; } } } err_ndp: /* are there more NDPs to process? */ ndpoffset = le16_to_cpu(ndp16->wNextFpIndex); if (ndpoffset && loopcount--) goto next_ndp; else { prcb->bIsOver=TRUE; } error: if (!NT_SUCCESS(NtStatus)) { prcb->bIsOver=TRUE; } return prcb->bIsOver; }