len := Mbuf.m_length(pkt_mbuf);
    (* copy data into its own mbuf chain *)
    this.pkt := Mbuf.m_gethdr(Mbuf.M_DONTWAIT, Mbuf.MT_DATA);
    IF len < Mbuf.MHLEN THEN
      this.pkt.mh_hdr.mh_len := len;
      (* Slow copy from mbuf chain to contiguous buffer -  ugh *)
      srcPos := 0; (* start copying after the headers *)
      dstPos := 0;
      WHILE pkt_mbuf # NIL DO
        WITH srcBuf = Mbuf.Array(pkt_mbuf)^,
             srcSize = BYTESIZE(srcBuf)-srcPos,
             dstBuf = Mbuf.Array(this.pkt)^
         DO
          IF srcSize >= 0 THEN
            SUBARRAY(dstBuf,dstPos,srcSize) :=
              SUBARRAY(srcBuf,srcPos,srcSize);
            srcPos := 0;
          ELSE
            DEC(srcPos,BYTESIZE(srcBuf));
          END;
          INC(dstPos,srcSize);
        END;
        pkt_mbuf := pkt_mbuf.mh_hdr.mh_next;
      END;
    ELSE
      this.pkt.mh_hdr.mh_len := 0;
      Mbuf.MH_ALIGN(pkt_mbuf,Mbuf.MHLEN);
      data := Mbuf.m_copym(pkt_mbuf,0,len,Mbuf.M_WAIT);
      this.pkt.mh_hdr.mh_next := data;
    END;
    MbufPublic.SetPktHdrLen(this.pkt,len);