struct usb_cdc_ncm_ndp16 *ncm0;
        struct usb_cdc_ncm_dpe16 *dpe;
        struct ipheth_device *dev;
+       u16 dg_idx, dg_len;
        int retval = -EINVAL;
        char *buf;
-       int len;
 
        dev = urb->context;
 
        ncmh = urb->transfer_buffer;
        if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
            /* On iOS, NDP16 directly follows NTH16 */
-           ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16))) {
-               dev->net->stats.rx_errors++;
-               return retval;
-       }
+           ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)))
+               goto rx_error;
 
        ncm0 = urb->transfer_buffer + sizeof(struct usb_cdc_ncm_nth16);
-       if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) {
-               dev->net->stats.rx_errors++;
-               return retval;
-       }
+       if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN))
+               goto rx_error;
 
        dpe = ncm0->dpe16;
-       while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
-              le16_to_cpu(dpe->wDatagramLength) != 0) {
-               if (le16_to_cpu(dpe->wDatagramIndex) < IPHETH_NCM_HEADER_SIZE ||
-                   le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
-                   le16_to_cpu(dpe->wDatagramLength) > urb->actual_length -
-                   le16_to_cpu(dpe->wDatagramIndex)) {
+       while (true) {
+               dg_idx = le16_to_cpu(dpe->wDatagramIndex);
+               dg_len = le16_to_cpu(dpe->wDatagramLength);
+
+               /* Null DPE must be present after last datagram pointer entry
+                * (3.3.1 USB CDC NCM spec v1.0)
+                */
+               if (dg_idx == 0 && dg_len == 0)
+                       return 0;
+
+               if (dg_idx < IPHETH_NCM_HEADER_SIZE ||
+                   dg_idx >= urb->actual_length ||
+                   dg_len > urb->actual_length - dg_idx) {
                        dev->net->stats.rx_length_errors++;
                        return retval;
                }
 
-               buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
-               len = le16_to_cpu(dpe->wDatagramLength);
+               buf = urb->transfer_buffer + dg_idx;
 
-               retval = ipheth_consume_skb(buf, len, dev);
+               retval = ipheth_consume_skb(buf, dg_len, dev);
                if (retval != 0)
                        return retval;
 
                dpe++;
        }
 
-       return 0;
+rx_error:
+       dev->net->stats.rx_errors++;
+       return retval;
 }
 
 static void ipheth_rcvbulk_callback(struct urb *urb)