ANSC_STATUS BbhmDiagnsRemove ( ANSC_HANDLE hThisObject ) { PBBHM_DIAG_NS_LOOKUP_OBJECT pMyObject = (PBBHM_DIAG_NS_LOOKUP_OBJECT)hThisObject; PBBHM_NS_LOOKUP_TDO_OBJECT pStateTimer = (PBBHM_NS_LOOKUP_TDO_OBJECT )pMyObject->hStateTimer; if ( pStateTimer ) { pStateTimer->Remove((ANSC_HANDLE)pStateTimer); } pMyObject->Close((ANSC_HANDLE)pMyObject); if ( pMyObject->hSendBuffer ) { AnscFreeMemory(pMyObject->hSendBuffer); pMyObject->hSendBuffer = NULL; } pMyObject->Cancel((ANSC_HANDLE)pMyObject); pMyObject->Reset ((ANSC_HANDLE)pMyObject); AnscFreeLock (&pMyObject->EchoTableLock); AnscFreeLock (&pMyObject->PqueryTableLock); AnscCoRemove(pMyObject); BbhmDiageoRemove((ANSC_HANDLE)pMyObject); return ANSC_STATUS_SUCCESS; }
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; } } }
ANSC_STATUS BbhmDiagnsInitialize ( ANSC_HANDLE hThisObject ) { PBBHM_DIAG_NS_LOOKUP_OBJECT pMyObject = (PBBHM_DIAG_NS_LOOKUP_OBJECT)hThisObject; /* * Until you have to simulate C++ object-oriented programming style with standard C, you don't * appreciate all the nice little things come with C++ language and all the dirty works that * have been done by the C++ compilers. Member initialization is one of these things. While in * C++ you don't have to initialize all the member fields inherited from the base class since * the compiler will do it for you, such is not the case with C. */ BbhmDiageoInitialize((ANSC_HANDLE)pMyObject); /* * Although we have initialized some of the member fields in the "create" member function, we * repeat the work here for completeness. While this simulation approach is pretty stupid from * a C++/Java programmer perspective, it's the best we can get for universal embedded network * programming. Before we develop our own operating system (don't expect that to happen any * time soon), this is the way things gonna be. */ pMyObject->Oid = BBHM_DIAG_NS_LOOKUP_OID; pMyObject->QueryId = 0; pMyObject->bActive = FALSE; pMyObject->Reset = BbhmDiagnsReset; pMyObject->CopyDiagParams = BbhmDiagnsCopyDiagParams; /* overwrite the virtual functions */ pMyObject->StartDiag = BbhmDiagnsStartDiag; pMyObject->StopDiag = BbhmDiagnsStopDiag; pMyObject->RetrieveResult = BbhmDiagnsRetrieveResult; pMyObject->ResetProperty = BbhmDiagnsResetProperty; pMyObject->ResetPropertyCounter = BbhmDiagnsResetPropertyCounter; pMyObject->Reset = BbhmDiagnsReset; pMyObject->Start = BbhmDiagnsStart; pMyObject->Stop = BbhmDiagnsStop; pMyObject->Open = BbhmDiagnsOpen; pMyObject->Close = BbhmDiagnsClose; pMyObject->Expire1 = BbhmDiagnsExpire1; pMyObject->Expire2 = BbhmDiagnsExpire2; pMyObject->SetStopTime = BbhmDiagnsSetStopTime; pMyObject->AddEchoEntry = BbhmDiagnsAddEchoEntry; pMyObject->PopEchoEntry = BbhmDiagnsPopEchoEntry; pMyObject->Recv = BbhmDiagnsRecv; pMyObject->Send = BbhmDiagnsSend; pMyObject->GetSrcIp = BbhmDiagnsGetSrcIp; pMyObject->SetSrcIp = BbhmDiagnsSetSrcIp; pMyObject->GetDstIp = BbhmDiagnsGetDstIp; pMyObject->SetDstIp = BbhmDiagnsSetDstIp; pMyObject->GetNumPkts = BbhmDiagnsGetNumPkts; pMyObject->SetNumPkts = BbhmDiagnsSetNumPkts; pMyObject->GetTimeOut = BbhmDiagnsGetTimeOut; pMyObject->SetTimeOut = BbhmDiagnsSetTimeOut; pMyObject->SetControl = BbhmDiagnsSetControl; pMyObject->SetStatus = BbhmDiagnsSetStatus; pMyObject->AddPquery = BbhmDiagnsAddPquery; pMyObject->GetPqueryById = BbhmDiagnsGetPqueryById; pMyObject->DelPquery = BbhmDiagnsDelPquery; pMyObject->DelAllPqueries = BbhmDiagnsDelAllPqueries; pMyObject->SetDiagParams = BbhmDiagnsSetDiagParams; pMyObject->CalculateResult = BbhmDiagnsCalculateResult; pMyObject->GetStatus = BbhmDiagnsGetStatus; /* * We shall initialize the session properties to the default values, which may be changed later * via the "configure" member function. If any of the future extensions needs to change the * session property, the following code also needs to be changed. */ pMyObject->ResetProperty((ANSC_HANDLE)pMyObject); AnscSListInitializeHeader(&pMyObject->EchoTable); AnscSListInitializeHeader(&pMyObject->PqueryTable); AnscInitializeLock (&pMyObject->EchoTableLock); AnscInitializeLock (&pMyObject->PqueryTableLock); return ANSC_STATUS_SUCCESS; }