ANSC_STATUS BbhmDiagipExpire2 ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBBHM_DIAG_IP_PING_OBJECT pMyObject = (PBBHM_DIAG_IP_PING_OBJECT )hThisObject; PBBHM_IP_PING_PROPERTY pProperty = (PBBHM_IP_PING_PROPERTY )&pMyObject->Property; PBBHM_IP_PING_TDO_OBJECT pStateTimer = (PBBHM_IP_PING_TDO_OBJECT )pMyObject->hStateTimer; PBBHM_IP_PING_SINK_OBJECT pSink = (PBBHM_IP_PING_SINK_OBJECT )pMyObject->hSinkObject; pMyObject->SetStatus((ANSC_HANDLE)pMyObject, BBHM_IP_PING_STATUS_TIMEOUT); pMyObject->Stop((ANSC_HANDLE)pMyObject); return returnStatus; }
ANSC_STATUS BbhmDiagipRecv ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSinkObject, PVOID buffer, ULONG ulSize ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBBHM_DIAG_IP_PING_OBJECT pMyObject = (PBBHM_DIAG_IP_PING_OBJECT)hThisObject; PBBHM_IP_PING_PROPERTY pProperty = (PBBHM_IP_PING_PROPERTY )&pMyObject->Property; PBBHM_IP_PING_TDO_OBJECT pStateTimer = (PBBHM_IP_PING_TDO_OBJECT )pMyObject->hStateTimer; PBBHM_IP_PING_SINK_OBJECT pSink = (PBBHM_IP_PING_SINK_OBJECT )hSinkObject; PANSC_XSOCKET_OBJECT pSocket = (PANSC_XSOCKET_OBJECT )pSink->GetXsocket((ANSC_HANDLE)pSink); PIPV4_HEADER pIpv4Header = (PIPV4_HEADER )NULL; /*PIPV6_HEADER pIpv6Header = (PIPV6_HEADER )NULL;*/ PICMPV4_ECHO_MESSAGE pIcmpHeader = (PICMPV4_ECHO_MESSAGE )NULL; PBBHM_IP_PING_ECHO_ENTRY pMEchoEntry = NULL; ULONG StopTime = 0; StopTime = AnscGetTickInMilliSeconds(); if ( pProperty->Status != BBHM_IP_PING_STATUS_RUNNING ) { return ANSC_STATUS_UNAPPLICABLE; } if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET ) { pIpv4Header = (PIPV4_HEADER)buffer; pIcmpHeader = (PICMPV4_ECHO_MESSAGE)AnscIpv4GetPayload(pIpv4Header); if ( ! AnscEqualString(pSocket->PeerName, pProperty->pDstAddrName, TRUE)/*(pSocket->PeerAddress.Value != pProperty->DstIp.Value)*/ || (AnscIcmpv4EchoGetId(pIcmpHeader) != tempId) ) { return ANSC_STATUS_FAILURE; } if ( (AnscIcmpv4EchoGetType(pIcmpHeader) == ICMP_TYPE_DESTINATION_UNREACHABLE) || (AnscIcmpv4EchoGetType(pIcmpHeader) == ICMP_TYPE_TIME_EXCEEDED) || (AnscIcmpv4EchoGetType(pIcmpHeader) == ICMP_TYPE_PARAMETER_PROBLEM) || (AnscIcmpv4EchoGetType(pIcmpHeader) == ICMP_TYPE_SOURCE_QUENCH) || (AnscIcmpv4EchoGetType(pIcmpHeader) == ICMP_TYPE_REDIRECT)) { pProperty->NumIcmpError ++; pProperty->IcmpError = AnscIcmpv4EchoGetType(pIcmpHeader); pMEchoEntry = (PBBHM_IP_PING_ECHO_ENTRY)AnscAllocateMemory(sizeof(BBHM_IP_PING_ECHO_ENTRY)); if ( pMEchoEntry ) { pMEchoEntry->ICMPType = AnscIcmpv4EchoGetType(pIcmpHeader); AnscAcquireLock(&pMyObject->MiddleResultLock); AnscSListPushEntryAtBack(&pMyObject->MiddleResult, &pMEchoEntry->Linkage); AnscReleaseLock(&pMyObject->MiddleResultLock); } return ANSC_STATUS_FAILURE; } returnStatus = pMyObject->SetStopTime ( (ANSC_HANDLE)pMyObject, AnscIcmpv4EchoGetSeqNumber(pIcmpHeader), AnscIpv4GetTotalLength(pIpv4Header) - sizeof(IPV4_HEADER) - sizeof(ICMPV4_HEADER), AnscIpv4GetTtl(pIpv4Header), StopTime ); } else if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET6 ) { pIcmpHeader = (PICMPV6_ECHO_MESSAGE)buffer; if ( ! AnscEqualString(pSocket->PeerName, pProperty->pDstAddrName, TRUE)/*(pSocket->PeerAddress.Value != pProperty->DstIp.Value)*/ || (AnscIcmpv6EchoGetId(pIcmpHeader) != tempId) ) { return ANSC_STATUS_FAILURE; } if ( (AnscIcmpv6EchoGetType(pIcmpHeader) == ICMP6_TYPE_DESTINATION_UNREACHABLE) || (AnscIcmpv6EchoGetType(pIcmpHeader) == ICMP6_TYPE_TIME_EXCEEDED) || (AnscIcmpv6EchoGetType(pIcmpHeader) == ICMP6_TYPE_PARAMETER_PROBLEM) || (AnscIcmpv6EchoGetType(pIcmpHeader) == ICMP6_TYPE_PACKET_TOO_BIG)) { pProperty->NumIcmpError ++; pProperty->IcmpError = AnscIcmpv6EchoGetType(pIcmpHeader); pMEchoEntry = (PBBHM_IP_PING_ECHO_ENTRY)AnscAllocateMemory(sizeof(BBHM_IP_PING_ECHO_ENTRY)); if ( pMEchoEntry ) { pMEchoEntry->ICMPType = AnscIcmpv6EchoGetType(pIcmpHeader); AnscAcquireLock(&pMyObject->MiddleResultLock); AnscSListPushEntryAtBack(&pMyObject->MiddleResult, &pMEchoEntry->Linkage); AnscReleaseLock(&pMyObject->MiddleResultLock); } return ANSC_STATUS_FAILURE; } returnStatus = pMyObject->SetStopTime ( (ANSC_HANDLE)pMyObject, AnscIcmpv6EchoGetSeqNumber(pIcmpHeader), ulSize, 0, /* Hop Limit */ StopTime ); } if ( returnStatus == ANSC_STATUS_SUCCESS ) { pProperty->PktsRecv ++; } if ( pProperty->PktsRecv == pProperty->NumPkts ) { pMyObject->SetStatus((ANSC_HANDLE)pMyObject, BBHM_IP_PING_STATUS_COMPLETE); pMyObject->Stop((ANSC_HANDLE)pMyObject); } return returnStatus; }
ANSC_STATUS BbhmDiagipStart ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBBHM_DIAG_IP_PING_OBJECT pMyObject = (PBBHM_DIAG_IP_PING_OBJECT)hThisObject; PDSLH_PING_INFO pDiagInfo = (PDSLH_PING_INFO)pMyObject->hDslhDiagInfo; PBBHM_IP_PING_PROPERTY pProperty = (PBBHM_IP_PING_PROPERTY )&pMyObject->Property; PBBHM_IP_PING_TDO_OBJECT pStateTimer = (PBBHM_IP_PING_TDO_OBJECT)pMyObject->hStateTimer; PBBHM_IP_PING_SINK_OBJECT pSink = (PBBHM_IP_PING_SINK_OBJECT)pMyObject->hSinkObject; PANSC_XSOCKET_OBJECT pSocket = (PANSC_XSOCKET_OBJECT )pSink->GetXsocket((ANSC_HANDLE)pSink); ULONG numPkts = pProperty->NumPkts; ULONG pktSize = pProperty->PktSize; PCHAR pSendBuffer = pMyObject->hSendBuffer; ULONG i = 0; PICMPV4_ECHO_MESSAGE pIcmpHeader = NULL; ULONG StartTime = 0; UCHAR SrcIp[4] = {0, 0, 0, 0}; if ( !pMyObject->bActive ) { pProperty->Status = BBHM_IP_PING_STATUS_ABORT; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } pMyObject->ResetPropertyCounter((ANSC_HANDLE)pMyObject); pSocket->SetPeerName ((ANSC_HANDLE)pSocket, pProperty->pDstAddrName); pSocket->SetHostName ((ANSC_HANDLE)pSocket, pProperty->pSrcAddrName); /* pSocket->SetHostAddress ((ANSC_HANDLE)pSocket, SrcIp ); pSocket->SetHostPort ((ANSC_HANDLE)pSocket, 0 ); */ /*pSocket->SetTransportType((ANSC_HANDLE)pSocket, ICMP_TRANSPORT );*/ pSocket->SetType ((ANSC_HANDLE)pSocket, ANSC_XSOCKET_TYPE_RAW ); pSocket->SetMode ((ANSC_HANDLE)pSocket, 0 ); pSocket->SetXsink ((ANSC_HANDLE)pSocket, (ANSC_HANDLE)pSink ); /* * The underlying socket wrapper may require an explicit startup() call, such is the case on * Microsoft windows platforms. The wrapper initialization has to done for each task. On most * real-time operating systems, this call is not required. */ AnscStartupXsocketWrapper((ANSC_HANDLE)pMyObject); /* For IPv4/IPv6 compatible purpose we shall resolve the address first */ returnStatus = BbhmDiagResolvAddr(hThisObject); if ( returnStatus != ANSC_STATUS_SUCCESS ) { pProperty->Status = BBHM_IP_PING_STATUS_ERROR_HostName; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } pMyObject->IPProtocol = pSocket->GetIpProtocol((ANSC_HANDLE)pSocket); if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET ) { pSocket->SetTransportType((ANSC_HANDLE)pSocket, IP4_PROTOCOL_ICMP); } else if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET6 ) { pSocket->SetTransportType((ANSC_HANDLE)pSocket, IP6_PROTOCOL_ICMP); } else { pProperty->Status = BBHM_IP_PING_STATUS_ABORT; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } /* * We shall open the socket and listen on it right away. Since we're still in the context of * initialiation, the wrapper module must be aware of the fact that the socket is opened before * the first call returns. */ returnStatus = pSocket->Bind((ANSC_HANDLE)pSocket); if ( returnStatus != ANSC_STATUS_SUCCESS ) { pProperty->Status = BBHM_IP_PING_STATUS_ABORT; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } returnStatus = pSocket->Open((ANSC_HANDLE)pSocket); /* Create recv task */ if ( returnStatus != ANSC_STATUS_SUCCESS ) { AnscTrace("Socket Open Failed!\n"); pProperty->Status = BBHM_IP_PING_STATUS_ABORT; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } if ( !pSendBuffer ) { returnStatus = ANSC_STATUS_FAILURE; pProperty->Status = BBHM_IP_PING_STATUS_ABORT; pMyObject->Stop(hThisObject); return ANSC_STATUS_FAILURE; } /* Set DSCP */ if ( pDiagInfo->DSCP != 0 ) { pSocket->ApplyDSCP((ANSC_HANDLE)pSocket, pDiagInfo->DSCP); } AnscSleep(100); if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET ) { pIcmpHeader = (PICMPV4_ECHO_MESSAGE)pMyObject->hSendBuffer; AnscIcmpv4EchoSetType (pIcmpHeader, ICMP_TYPE_ECHO_REQUEST ); AnscIcmpv4EchoSetCode (pIcmpHeader, 0 ); AnscIcmpv4EchoSetId (pIcmpHeader, tempId ); AnscIcmpv4EchoSetSeqNumber (pIcmpHeader, (USHORT)pMyObject->GetPktsSent((ANSC_HANDLE)pMyObject)); for ( i = 0; i < pktSize; i++ ) { ((PUCHAR)pMyObject->hSendBuffer)[i + sizeof(ICMPV4_HEADER)] = (UCHAR)i; } AnscIcmpv4EchoSetChecksum (pIcmpHeader, 0 ); AnscIcmpv4CalculateChecksum (((PICMPV4_HEADER)pIcmpHeader), pktSize + sizeof(ICMPV4_HEADER)); } else if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET6 ) { pIcmpHeader = (PICMPV6_ECHO_MESSAGE)pMyObject->hSendBuffer; AnscIcmpv6EchoSetType (pIcmpHeader, ICMP6_TYPE_ECHO_REQUEST ); AnscIcmpv6EchoSetCode (pIcmpHeader, 0 ); AnscIcmpv6EchoSetId (pIcmpHeader, tempId ); AnscIcmpv6EchoSetSeqNumber (pIcmpHeader, (USHORT)pMyObject->GetPktsSent((ANSC_HANDLE)pMyObject)); for ( i = 0; i < pktSize; i++ ) { ((PUCHAR)pMyObject->hSendBuffer)[i + sizeof(ICMPV6_HEADER)] = (UCHAR)i; } } pStateTimer->SetTimerType((ANSC_HANDLE)pStateTimer, ANSC_TIMER_TYPE_SPORADIC); pStateTimer->SetInterval ((ANSC_HANDLE)pStateTimer, pProperty->TimeBetween ); pStateTimer->SetCounter ((ANSC_HANDLE)pStateTimer, pProperty->NumPkts ); /* pSocket->SetPeerAddress ((ANSC_HANDLE)pSocket , pProperty->DstIp.Dot ); pSocket->SetPeerPort ((ANSC_HANDLE)pSocket , 0 ); */ pMyObject->SetStatus((ANSC_HANDLE)pMyObject, BBHM_IP_PING_STATUS_RUNNING); pStateTimer->Start ((ANSC_HANDLE)pStateTimer); StartTime = AnscGetTickInMilliSeconds(); if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET ) { returnStatus = pMyObject->AddEchoEntry ( (ANSC_HANDLE)pMyObject, AnscIcmpv4EchoGetSeqNumber(pIcmpHeader), StartTime ); returnStatus = pMyObject->Send ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pMyObject->hSinkObject, (PVOID)pMyObject->hSendBuffer, pktSize + sizeof(ICMPV4_HEADER) ); } else if ( pMyObject->IPProtocol == XSKT_SOCKET_AF_INET6 ) { returnStatus = pMyObject->AddEchoEntry ( (ANSC_HANDLE)pMyObject, AnscIcmpv6EchoGetSeqNumber(pIcmpHeader), StartTime ); returnStatus = pMyObject->Send ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pMyObject->hSinkObject, (PVOID)pMyObject->hSendBuffer, pktSize + sizeof(ICMPV6_HEADER) ); } pProperty->PktsSent++; return returnStatus; }