ANSC_STATUS
BbhmDiagnsStopDiag
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus        = ANSC_STATUS_SUCCESS;
    PBBHM_DIAG_NS_LOOKUP_OBJECT     pMyObject           = (PBBHM_DIAG_NS_LOOKUP_OBJECT  )hThisObject;

    if ( !(pMyObject->CheckCanStart((ANSC_HANDLE)pMyObject)))
    {
        returnStatus = pMyObject->SetControl((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_CONTROL_STOP);

        return  returnStatus;
    }
    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
BbhmDiagnsRecv
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hXsinkObject,
        PVOID                       buffer,
        ULONG                       ulSize
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PBBHM_DIAG_NS_LOOKUP_OBJECT     pMyObject    = (PBBHM_DIAG_NS_LOOKUP_OBJECT )hThisObject;
    PBBHM_NS_LOOKUP_PROPERTY        pProperty    = (PBBHM_NS_LOOKUP_PROPERTY    )&pMyObject->Property;
    PBBHM_NS_LOOKUP_TDO_OBJECT      pStateTimer  = (PBBHM_NS_LOOKUP_TDO_OBJECT  )pMyObject->hStateTimer;
    PBBHM_NS_LOOKUP_XSINK_OBJECT    pXsink       = (PBBHM_NS_LOOKUP_XSINK_OBJECT)hXsinkObject;
    PANSC_XSOCKET_OBJECT            pXsocket     = (PANSC_XSOCKET_OBJECT        )pXsink->GetXsocket((ANSC_HANDLE)pXsink);
    PDSLH_NSLOOKUP_INFO             pDiagInfo    = (PDSLH_NSLOOKUP_INFO         )pMyObject->hDslhDiagInfo;
    PDNS_HEADER                     pDnsHeader   = (PDNS_HEADER)buffer;
    PBBHM_NS_LOOKUP_ECHO_ENTRY      pEchoEntry   = NULL;
    PBBHM_NS_LOOKUP_QUERY_ENTRY     pQuery       = NULL;
    ULONG                           StopTime     = 0;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = NULL;
    char*                           p            = NULL;

    StopTime = AnscGetTickInMilliSeconds();


    if ( pProperty->Status != BBHM_NS_LOOKUP_STATUS_RUNNING )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }

    /* Temporarily disable this check since we will check pQuery later */
/*
    if ( pXsocket->PeerAddress.Value != pProperty->DstIp.Value )
    {
        return  ANSC_STATUS_FAILURE;
    }
*/

    pQuery = pMyObject->GetPqueryById(pMyObject, AnscDnsGetId(pDnsHeader));
    if ( pQuery )
    {
        if ( AnscDnsGetRcode(pDnsHeader) != 0 )
        {
            if ( AnscDnsGetRcode(pDnsHeader) == DNS_RCODE_NAME_ERROR )
            {
                p = pDiagInfo->HostName + AnscSizeOfString(pDiagInfo->HostName) + 1;

                if ( AnscSizeOfString(p) )
                {
                    if ( !AnscEqualString(p - AnscSizeOfString(p) - 1, p, TRUE) )
                    {
                        pStateTimer->Stop((ANSC_HANDLE)pStateTimer);
                        pProperty->Control = BBHM_NS_LOOKUP_CONTROL_STOP;
                        pMyObject->DelAllPqueries(hThisObject);
                        pMyObject->PopEchoEntry(hThisObject);
                        pMyObject->ResetPropertyCounter(hThisObject);

                        *(p - 1) = '.';
                        pMyObject->SetControl   ((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_CONTROL_START);
                        BbhmDiageoStartDiag     ((ANSC_HANDLE)pMyObject);
                        return  ANSC_STATUS_SUCCESS;
                    }
                }
            }


            pSLinkEntry = AnscSListGetFirstEntry(&pMyObject->EchoTable);

            while ( pSLinkEntry )
            {
                pEchoEntry  = ACCESS_BBHM_NS_LOOKUP_ECHO_ENTRY(pSLinkEntry);
                pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry);

                if ( pQuery->QueryId == pEchoEntry->QueryId )
                {
                    break;
                }
            }

            if ( AnscDnsGetRcode(pDnsHeader) == DNS_RCODE_NAME_ERROR )
            {
                pEchoEntry->Status = BBHM_NS_LOOKUP_STATUS_Error_HostNameNotResolved;
            }
            else if ( AnscDnsGetRcode(pDnsHeader) == DNS_RCODE_SERVER_FAILURE ||  AnscDnsGetRcode(pDnsHeader) == DNS_RCODE_REFUSED )
            {
                pEchoEntry->Status = BBHM_NS_LOOKUP_STATUS_Error_DNSServerNotAvailable;
            }
            else
            {
                pEchoEntry->Status = BBHM_NS_LOOKUP_STATUS_Error_Other;
            }
            pEchoEntry->AnswerType = AnscDnsIsAuthoritativeAnswer(pDnsHeader) ? BBHM_NS_LOOKUP_RESULT_Authoritative : BBHM_NS_LOOKUP_RESULT_NonAuthoritative;
            pEchoEntry->HostNameReturned = NULL;
            pEchoEntry->IPAddresses = NULL;
            pMyObject->DelPquery(pMyObject, pQuery);

            pProperty->PktsRecv++;
        }
        else
        {
            returnStatus = pMyObject->SetStopTime((ANSC_HANDLE)pMyObject, pQuery, pDnsHeader, StopTime);

            if ( returnStatus == ANSC_STATUS_SUCCESS )
            {
                pProperty->PktsRecv++;
            }
        }

        if ( pProperty->PktsRecv == pProperty->NumPkts )
        {
            pMyObject->SetStatus((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_STATUS_COMPLETE);
            pMyObject->Stop((ANSC_HANDLE)pMyObject);
        }

        return  returnStatus;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
BbhmDiagnsStartDiag
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus        = ANSC_STATUS_SUCCESS;
    PBBHM_DIAG_NS_LOOKUP_OBJECT     pMyObject           = (PBBHM_DIAG_NS_LOOKUP_OBJECT)hThisObject;
    PDSLH_NSLOOKUP_INFO             pDiagInfo           = (PDSLH_NSLOOKUP_INFO)pMyObject->hDslhDiagInfo;
    PBBHM_NS_LOOKUP_PROPERTY        pProperty           = (PBBHM_NS_LOOKUP_PROPERTY   )&pMyObject->Property;

    if ( pDiagInfo->bForced != FALSE )
    {
        if ( !(pMyObject->CheckCanStart((ANSC_HANDLE)pMyObject)))
        {
            returnStatus = pMyObject->SetControl((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_CONTROL_STOP);
        }
        pMyObject->ResetProperty    ((ANSC_HANDLE)pMyObject);

        if ( pMyObject->SetDstIp    ((ANSC_HANDLE)pMyObject, pDiagInfo->DNSServer) == ANSC_STATUS_SUCCESS)
        {
            pMyObject->SetNumPkts   ((ANSC_HANDLE)pMyObject, pDiagInfo->NumberOfRepetitions);
            pMyObject->SetSrcIp     ((ANSC_HANDLE)pMyObject, pDiagInfo->IfAddr );
            pMyObject->SetTimeOut   ((ANSC_HANDLE)pMyObject, pDiagInfo->Timeout);

            pMyObject->Open         (pMyObject);
            pMyObject->SetControl   ((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_CONTROL_START);
            BbhmDiageoStartDiag     ((ANSC_HANDLE)pMyObject);
        }
        else
        {
            pDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Error_NSLookup_DNSServer;
        }
        return ANSC_STATUS_SUCCESS;
    }
    else
    {
        if ( pMyObject->CheckCanStart   ((ANSC_HANDLE)pMyObject) )
        {
            pMyObject->ResetProperty    ((ANSC_HANDLE)pMyObject);

            if ( pMyObject->SetDstIp    ((ANSC_HANDLE)pMyObject, pDiagInfo->DNSServer) == ANSC_STATUS_SUCCESS)
            {
                pMyObject->SetNumPkts   ((ANSC_HANDLE)pMyObject, pDiagInfo->NumberOfRepetitions);
                pMyObject->SetSrcIp     ((ANSC_HANDLE)pMyObject, pDiagInfo->IfAddr );
                pMyObject->SetTimeOut   ((ANSC_HANDLE)pMyObject, pDiagInfo->Timeout);

                pMyObject->Open         ((ANSC_HANDLE)pMyObject);
                pMyObject->SetControl   ((ANSC_HANDLE)pMyObject, BBHM_NS_LOOKUP_CONTROL_START);
                BbhmDiageoStartDiag     ((ANSC_HANDLE)pMyObject);
            }
            else
            {
                pDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Error_NSLookup_DNSServer;
            }
            return ANSC_STATUS_SUCCESS;
        }
        else
        {
            AnscTraceFlow(("BbhmDiagnsStartDiag -- query task is already running...\n"));

            return  ANSC_STATUS_PENDING;
        }
    }
}