bool CTun::collectIp6Packet(IpPacket::IPv6* p_poPacket, ssize_t br) { if (br < (ssize_t)offsetof(IpPacket::IPv6, m_oIP_Payload)) { NLOG_WARN("CTun::collectIp6Packet, [IP] header too small: expected(0x%04x), received(0x%04x)", offsetof(IpPacket::IPv6, m_oIP_Payload), br); return false; } // verify packet length uint16_t rcvLen = ntohs(p_poPacket->m_u16_PayloadLength); if(rcvLen + (ssize_t)offsetof(IpPacket::IPv6, m_oIP_Payload) != br) { NLOG_WARN("CTun::collectIp6Packet, [IP] packet size wrong: expected(0x%04x), received(0x%04x)", rcvLen + offsetof(IpPacket::IPv6, m_oIP_Payload), br); return false; } // verify checksums Ip6PseudoHdr oPHdr(p_poPacket); uint16_t rcvChecksum; // pseudoheader checksum uint16_t expChecksum = IpPacket::Checksum((uint8_t*)&oPHdr, sizeof oPHdr); switch(p_poPacket->m_u8_NextHeader) { case IPPROTO_ICMPV6: { rcvChecksum = ntohs(p_poPacket->m_oICMP_Payload.m_u16_Checksum); p_poPacket->m_oICMP_Payload.m_u16_Checksum = 0; expChecksum = IpPacket::Checksum((const uint8_t*)(&p_poPacket->m_oICMP_Payload), rcvLen, expChecksum); if (expChecksum != rcvChecksum) { NLOG_WARN("CTun::collectIp6Packet, [ICMP] incorrect checksum: expected(0x%04x), received(0x%04x)", expChecksum, rcvChecksum); return false; } p_poPacket->m_oICMP_Payload.m_u16_Checksum = htons(rcvChecksum); break; } case IPPROTO_UDP: { rcvChecksum = ntohs(p_poPacket->m_oUDP_Payload.m_u16_Checksum); if (!rcvChecksum){ //IPv6 receivers must discard UDP packets containing a zero checksum, and should log the error. NLOG_ERR("CTun::collectIp6Packet, [UDP] incorrect zero checksum: packet discarded"); return false; }; p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0; expChecksum = IpPacket::Checksum((uint8_t*)&p_poPacket->m_oUDP_Payload, rcvLen, expChecksum); if(!expChecksum ) expChecksum = 0xFFFF; if (expChecksum != rcvChecksum) { NLOG_WARN("CTun::collectIp6Packet, [UDP] incorrect checksum: expected(0x%04x), received(0x%04x)", expChecksum, rcvChecksum); return false; } p_poPacket->m_oUDP_Payload.m_u16_Checksum = htons(rcvChecksum); break; } default:; } return true; }
////////////////////////////////////////////////////////////////////////////// /// @brief Will try to connect using the socket that should be used /// @retval true if everything is ok, false otherwise /// @param [in] p_szHost Host where to connect (IP of hostname) /// @param [in] p_nPort Destination port to connect /// @param [in] p_nTimeout Timeout expressed in seconds for connection ////////////////////////////////////////////////////////////////////////////// bool CAbstractSocket::Connect(const char *p_szHost, unsigned short p_nPort, unsigned short p_nTimeout /*= 10*/) { // Check parameters if(p_szHost == NULL || p_szHost[0] == 0 || p_nPort == 0) { NLOG_WARN("Cannot connect to NULL host or port 0."); return false; } if(m_bSSLFlag) { bool bConnect = m_oSecureSocket.Connect(p_szHost, p_nPort, p_nTimeout); if(!bConnect) return false; if(!m_oSecureSocket.BlockUntilSSLServerHandshakeCompletes()) { NLOG_ERR("Cannot block until SSL handshake completes!"); return false; } return bConnect; } else return m_oNormalSocket.Connect(p_szHost, p_nPort, p_nTimeout); }
bool CTun::CollectPacket(IpPacket* p_poPacket) { if (!checkRead(10000)) { return false; } ssize_t br = read(m_nTunHandle, p_poPacket, MAX_IP_PACKET_SIZE); if(br < 0) { PERR("CTun::CollectPacket, read "TUN_INTERFACE); return false; } NLOG_DBG("CollectPacket, if:%s, sz:%d, data[%s%s]", m_szTunName, br, GET_HEX_LIMITED(&p_poPacket, (size_t)br, m_uHexLimit)); if (br < 1) { NLOG_WARN("CTun::CollectPacket, IP header too small: expected(1), received(0)"); return false; } int nIPversion = p_poPacket->Version(); switch(nIPversion){ case 4: return collectIp4Packet(&p_poPacket->m_stIp4, br); case 6: return collectIp6Packet(&p_poPacket->m_stIp6, br); default: return false; } }
void CIPGRegUpdCmd::Execute() { NLOG_INFO("[IPGRegUpdCmd]: received msg = %s", MsgToStr(m_rMsg).c_str()); CMgmtPOption::OptionIPGatewayInfoData *pOpData1 = NULL; std::list<CMgmtPOption::OptionIPRoutesListData> rawRouteInfo; CMgmtPOption::OptionKeepAliveIntervalData *pOpData2 = NULL; if (!ProcessMsg(&pOpData1, rawRouteInfo, &pOpData2)) { if (m_rIPGList.find(CIPGInfo (m_rMsg.m_oNetAddr)) == m_rIPGList.end()) NLOG_ERR("[IPGRegUpdCmd]: MODULE=%s was not added in CACHE because of invalid register/update INFO ", AddrToStr(m_rMsg.m_oNetAddr).c_str()); return; } ///add module if it doesn't exist CIPGInfo key(m_rMsg.m_oNetAddr); std::set<CIPGInfo>::iterator i = m_rIPGList.find(key); bool isNewIPG = false; if (i == m_rIPGList.end()) { ///FIRST CTunnelKey info(pOpData1->m_IPGAddrIPv4, pOpData1->m_szIPGAddrIPv6, 128); if (m_rFARAndIPGPubInf.insert(info).second == false) { NLOG_WARN("[IPGRegUpdCmd]: MODULE=%s was not added in CACHE because of duplicated publicInfo=%s, " "skip processing msg = %s", AddrToStr(m_rMsg.m_oNetAddr).c_str(), TunnelKeyToStr(info).c_str(), MsgToStr(m_rMsg).c_str()); return; } isNewIPG = true; i = m_rIPGList.insert(CIPGInfo(m_rMsg.m_oNetAddr, CModuleInfo::MT_REGISTERED)).first; i->SetPendingTimedout(m_rApp.GetConfig().m_nPendingRelationTimedoutS); } CIPGInfo *pIPGInfo = (CIPGInfo*)&(*i); pIPGInfo->SetTimedOut(CModuleInfo::MTT_KEEP_ALIVE, pOpData2->m_IntSec, pOpData2->m_IntUSec); pIPGInfo->SetPublicIpgInfo(*pOpData1); if(pIPGInfo->GetState() != CModuleInfo::MT_REGISTERED) pIPGInfo->SetState(CModuleInfo::MT_REGISTERED); ///process std::list<CMgmtPOption::OptionIPRoutesListData> IPGAddedRoute; std::list<CMgmtPOption::OptionIPRoutesListData> IPGEraseRoute; ProcessRegIPG(i, isNewIPG, rawRouteInfo, IPGAddedRoute, IPGEraseRoute); NLOG_INFO("[IPGRegUpdCmd]: raw(routes=%d), add(routes=%d), erase(routes=%d)", rawRouteInfo.size(), IPGAddedRoute.size(), IPGEraseRoute.size()); ///send result if (IPGAddedRoute.size() > 0) //SendAddTunnOnIPG(m_rMsg.m_oNetAddr, IPGAddedTun); -- not add only the difference but all SendSetTunnOnIPG(i); if (IPGEraseRoute.size() > 0) SendDelTunnOnIPG(m_rMsg.m_oNetAddr, IPGEraseRoute, m_rApp); }
/////////////////////////////////////////////////////////////////////////////// ///@author Ghervase Gabriel ///@brief Checks if a full messasge can be read from the usb ///@param [in]p_nMiliSec - How much to wait for data before abandoning the operation ///@retval false if no data or error ///@retval true if we have data /////////////////////////////////////////////////////////////////////////////// bool CFragmentedUSBLink::HaveData(unsigned int p_nMiliSec/* = 10*/) { if (m_bHaveFullPacket) { return m_bHaveFullPacket; } USBFragment ofragment; while (getFragment(ofragment, p_nMiliSec)) { //check messageId - if unexpected, drop previously read data and restart with new messageID if (m_nExpectedMessageId != ofragment.msgId) { //dump previously received data (if any) dropExistingReadData(); m_nExpectedMessageId = ofragment.msgId; } // ignore - duplicate packet received if (ofragment.pktNo < m_u8ExpectedPktNo) { continue; } // packets should arrive in order ; dump previously received data if not if (ofragment.pktNo > m_u8ExpectedPktNo) { NLOG_WARN("[CFragmentedUSBLink][HaveData] Bad pktNo received : %d > expected %d - Discard existing fragments for msgId %d ", (int)(ofragment.pktNo), (int)(m_u8ExpectedPktNo), (int)(ofragment.msgId) ); dropExistingReadData(); continue; } if (m_nBytesReceivedSoFar + FRAGMENT_DATA_SIZE > MAX_USB_PACKET_SIZE) { NLOG_ERR("[CFragmentedUSBLink][HaveData] Internal Buffer too small; is %d and we need %d - Discard existing fragments for msgId %d", (int)MAX_USB_PACKET_SIZE, (int)(m_nBytesReceivedSoFar + FRAGMENT_DATA_SIZE), (int)(ofragment.msgId)); dropExistingReadData(); continue; } memcpy(m_pu8ReadBuf + m_nBytesReceivedSoFar, ofragment.data, FRAGMENT_DATA_SIZE); m_nBytesReceivedSoFar += FRAGMENT_DATA_SIZE; m_u8ExpectedPktNo++; if (ofragment.notLastFragment) { continue; } //we have received the last fragment m_bHaveFullPacket = true; break; } return m_bHaveFullPacket; }
////////////////////////////////////////////////////////////////////////////// /// @brief Will try to send a message using the correct socket /// @retval true if everything is ok, false otherwise /// @param [in] p_pcMessage Pointer to a buffer containing the message /// @param [in] p_nLen Length of data in p_pcMessage /// @param [in] p_nFlags Specific flags, like OOB used to send the message ////////////////////////////////////////////////////////////////////////////// bool CAbstractSocket::Send(const void *p_pcMessage, int p_nLen, int p_nFlags /*= 0*/) { // Check parameters if(p_pcMessage == NULL || p_nLen < 0) { NLOG_WARN("Cannot send NULL packet, or with size smaller than 0."); return false; } if(m_bSSLFlag) return m_oSecureSocket.Send(p_pcMessage, p_nLen, p_nFlags); else return m_oNormalSocket.Send(p_pcMessage, p_nLen, p_nFlags); }
////////////////////////////////////////////////////////////////////////////// /// @brief Will read data from kernel internal received data buffers /// @retval true if everything is ok, false otherwise /// @param [in] p_pcMessage An allocated buffer where to store data /// @param [out] p_nLen Length of received data/size of the buffer [in] /// @param [in] p_nFlags Special flags, like OOB ////////////////////////////////////////////////////////////////////////////// bool CAbstractSocket::Recv(void *p_pcMessage, int &p_nLen, int p_nFlags /*= 0*/) { // Check buffer if(p_pcMessage == NULL) { NLOG_WARN("Cannot recv data in NULL buffer."); return false; } if(m_bSSLFlag) return m_oSecureSocket.Recv(p_pcMessage, p_nLen, p_nFlags); else return m_oNormalSocket.Recv(p_pcMessage, p_nLen, p_nFlags); }
void CRplRootNetStat :: Init( unsigned int p_unStatPeriodSec, unsigned int p_unNetStatGuardSec ) { NLOG_INFO( "CRplRootNetStat::Init()" ); if ( p_unStatPeriodSec == 0 ) { NLOG_WARN( "CRplRootNetStat::Init(): Can not start with period 0." ); return; } m_oCrntRecord.Init( p_unStatPeriodSec ); m_unNetStatGuardSec = p_unNetStatGuardSec; m_bOn = true; }
void CRplRootApp::SendNotificationForMac ( const uint8_t* p_pu8Mac, CMapShortAddrMgr::DeviceType4E p_pDeviceType4E ) { CRplTopology::CRplTopologyNode* pNode = g_pApp->m_pRplTopology->GetNewestNodeOnlyByMac ( p_pu8Mac ); if ( !pNode ) { NLOG_WARN ( "SendNotificationForMac, mac=%s is not RPL registered yet", FormatHex ( p_pu8Mac, 8, -1 ) ); return; } AddTopologyNotificationEncap ( MgmtProtocol::CMgmtPMessage::EVENT_REGISTER, NULL, pNode->m_oAddress, DeviceType4EToDeviceTypeMgmtP ( p_pDeviceType4E, (const TIpv6Addr *)&pNode->m_oAddress), GetFarId ( ), MgmtProtocol::TYPE_GR ); }
MgmtProtocol::CMgmtPMessage::Ptr CRplRootNetStat :: ReportMgmtMessage( MgmtProtocol::CMgmtPMessage::Ptr &p_pMessage ) { MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData oMsgNetStatComm; bool prev; if ( !p_pMessage->GetData( &oMsgNetStatComm ) ) { NLOG_WARN( "ReportMgmtMessage: Invalid NetStat request." ); } p_pMessage->m_Header.SetMsgType( MgmtProtocol::CMgmtPMessage::FAR_NETSTAT, true ); p_pMessage->m_Header.m_u8DestinationType = p_pMessage->m_Header.m_u8SourceType; p_pMessage->m_Header.m_u8SourceType = MgmtProtocol::MOD_GR; if (oMsgNetStatComm.m_ucFlags & MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData::LastPeriod ) { NLOG_INFO( "ReportMgmtMessage: reporting on previous record." ); prev = true; } else { NLOG_INFO( "ReportMgmtMessage: reporting on current record." ); prev = false; } if (oMsgNetStatComm.m_ucFlags & MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData::ResetCurrentStats ) { NLOG_INFO( "ReportMgmtMessage: resetting records." ); } else { NLOG_INFO( "ReportMgmtMessage: not resetting stats." ); } FarNetStatRecord &rReportedRecord = ( oMsgNetStatComm.m_ucFlags & MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData::LastPeriod ) ? m_oPrevRecord : m_oCrntRecord; SetMgmtMessageData(p_pMessage, rReportedRecord, prev); //if (!( oMsgNetStatComm.m_ucFlags & MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData::LastPeriod )) // m_oPrevRecord = m_oCrntRecord; if ( oMsgNetStatComm.m_ucFlags & MgmtProtocol::CMgmtPMessage::MsgFarNetStatCommData::ResetCurrentStats ) m_oCrntRecord.ResetStats(); return p_pMessage; }
/////////////////////////////////////////////////////////////////////////////// ///@author Gabriel Ghervase ///@brief Writes a fragment ///@param [in]p_rFragment - the fragment to write ///@retval true if fragment was written; false otherwise /////////////////////////////////////////////////////////////////////////////// bool CFragmentedUSBLink::putFragment(const USBFragment& p_rFragment) { int retval = CUSBLink::WriteBulk((unsigned char*)&p_rFragment, sizeof(USBFragment)); if ( retval < 0 ) { NLOG_ERR("[CFragmentedUSBLink][WriteBulk] Error writing - Abort"); return false; } if (retval == 0) { NLOG_WARN("[CFragmentedUSBLink][WriteBulk] wrote 0 bytes out of %d", sizeof(USBFragment)); return false ; //no error ; nothing tor read } return true; }
bool CTun::injectIp6Packet(IpPacket::IPv6* p_poPacket) { /* ipv6 payload + ipv6 header itself */ ssize_t packetLen = ntohs(p_poPacket->m_u16_PayloadLength) + offsetof(IpPacket::IPv6, m_oIP_Payload); if (packetLen > MAX_IP_PACKET_SIZE) { NLOG_WARN("CTun::injectIp6Packet, packetLen(%d) > MAX_PACKET_SIZE(%d)", packetLen, MAX_IP_PACKET_SIZE ); return false; } Ip6PseudoHdr oPHdr(p_poPacket); // pseudoheader checksum uint16_t checksum = IpPacket::Checksum((uint8_t*)&oPHdr, sizeof oPHdr); switch(p_poPacket->m_u8_NextHeader) { case IPPROTO_ICMPV6: p_poPacket->m_oICMP_Payload.m_u16_Checksum = 0; /* substract the ipv6 header size from the whole packet length */ p_poPacket->m_oICMP_Payload.m_u16_Checksum = htons(IpPacket::Checksum((const uint8_t*)&p_poPacket->m_oICMP_Payload, packetLen - offsetof(IpPacket::IPv6, m_oIP_Payload), checksum)); break; case IPPROTO_UDP: p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0; /* substract the ipv6 header size from the whole packet length */ checksum = IpPacket::Checksum((const uint8_t*)&p_poPacket->m_oUDP_Payload , packetLen - offsetof(IpPacket::IPv6, m_oIP_Payload), checksum); if(!checksum){ p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0xFFFF; }else{ p_poPacket->m_oUDP_Payload.m_u16_Checksum = htons(checksum); } break; default: NLOG_ERR("CTun::injectIp6Packet: unsupported IP next header %d, discarding packet", p_poPacket->m_u8_NextHeader); return false; } ssize_t bw = write(m_nTunHandle, p_poPacket, packetLen); if(bw < packetLen) { PERR("CTun::injectIp6Packet, write "TUN_INTERFACE); return false; } NLOG_DBG("injectIp6Packet, if:%s, sz:%d, data[%s%s]", m_szTunName, bw, GET_HEX_LIMITED(&p_poPacket, (size_t)bw, m_uHexLimit)) return true; }
/////////////////////////////////////////////////////////////////////////////// ///@author Gabriel Ghervase ///@brief Reads a fragment from the USB device ///@param [out]p_rFragment - the fragment where to write the received data ///@param [in]p_nMiliSec - timeout ///@retval true - got fragment ; false otherwise /////////////////////////////////////////////////////////////////////////////// bool CFragmentedUSBLink::getFragment(USBFragment& p_rFragment, unsigned int p_nMiliSec/* = 10*/) { int retval = CUSBLink::ReadBulk((unsigned char*)&p_rFragment, sizeof(USBFragment), p_nMiliSec); if ( retval < 0) { NLOG_ERR("[CFragmentedUSBLink][ReadBulk] Error reading - Abort"); return false; } if (retval == 0) { NLOG_WARN("[CFragmentedUSBLink][ReadBulk] Nothing to read"); return false ; //no error ; nothing tor read } return true; }
bool CTun::injectIp4Packet(IpPacket::IPv4* p_poPacket) { ssize_t packetLen = ntohs(p_poPacket->m_u16_TotalLength); if (packetLen > MAX_IP_PACKET_SIZE) { NLOG_WARN("CTun::injectIp4Packet, packetLen(%d) > MAX_IP_PACKET_SIZE(%d)", packetLen, MAX_IP_PACKET_SIZE ); return false; } switch(p_poPacket->m_u8_Protocol) { case IPPROTO_ICMP: p_poPacket->m_oICMP_Payload.m_u16_Checksum = 0; p_poPacket->m_oICMP_Payload.m_u16_Checksum = IpPacket::Checksum((const uint8_t*)(&p_poPacket->m_oICMP_Payload), packetLen - 4 * p_poPacket->IHL()); p_poPacket->m_oICMP_Payload.m_u16_Checksum = htons(p_poPacket->m_oICMP_Payload.m_u16_Checksum ); break; case IPPROTO_UDP: { Ip4UDPPseudoHdr oPHdr(p_poPacket); // pseudoheader checksum uint16_t checksum = IpPacket::Checksum((uint8_t*)&oPHdr, sizeof (Ip4UDPPseudoHdr)); p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0; checksum = IpPacket::Checksum((uint8_t*)&p_poPacket->m_oUDP_Payload, ntohs(oPHdr.m_u16_UDP_length), checksum); if(!checksum){ p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0xFFFF; }else{ p_poPacket->m_oUDP_Payload.m_u16_Checksum = htons(checksum); } break; } default:; } p_poPacket->m_u16_Checksum = 0; p_poPacket->m_u16_Checksum = htons(IpPacket::Checksum((const uint8_t*)p_poPacket, p_poPacket->IHL()*4)); ssize_t bw = write(m_nTunHandle, p_poPacket, packetLen); if(bw < packetLen) { PERR("CTun::injectIp4Packet, write "TUN_INTERFACE); return false; } NLOG_DBG("injectIp4Packet, if:%s, sz:%d, data[%s%s]", m_szTunName, bw, GET_HEX_LIMITED(&p_poPacket, (size_t)bw, m_uHexLimit)) return true; }
int CConfig_DNS::Init(const char* p_szModuleName) { if (!CConfig::Init(p_szModuleName)) return 0; READ_DEFAULT_VARIABLE_INT("PORT", m_nPort, DEFAULT_PORT); READ_DEFAULT_VARIABLE_INT("RELOAD_PERIOD", m_nReloadPeriodSeconds, DEFAULT_RELOAD_PERIOD); READ_DEFAULT_VARIABLE_NET_ADDR_EXT("NOTIF_ADDR", m_oNotifAddr, DEFAULT_NOTIF_ADDR); /*********************************************************************** * Load name patterns **********************************************************************/ char szPatternValue[MAX_PATTERN_LEN]; for (int pos = 0; GetVar("NAME_PATTERN", szPatternValue, sizeof szPatternValue, pos); ++pos) { char szPrefix[MAX_PATTERN_LEN] = { 0, }; unsigned uDeviceIdLen = 0; char szSuffix[MAX_PATTERN_LEN] = { 0, }; if ( int p = sscanf( szPatternValue, "%[0-9a-zA-Z._-],%d,%[0-9a-zA-Z._-]", szPrefix, &uDeviceIdLen, szSuffix ) < 3 ) { NLOG_WARN( "Read %d parts (exp=3) from name pattern=%s", p, szPatternValue ); } CQNamePatternMatcher oQNamePatternMatcher; oQNamePatternMatcher.CompilePattern( szPrefix, 16, szSuffix ); m_oQNamePatternMatcherList.push_back( oQNamePatternMatcher ); } if (m_oQNamePatternMatcherList.empty()) { NLOG_INFO("Load default pattern"); CQNamePatternMatcher oQNamePatternMatcher; oQNamePatternMatcher.CompilePattern(DEFAULT_URL_PREFIX, 16, DEFAULT_URL_SUFFIX); m_oQNamePatternMatcherList.push_back(oQNamePatternMatcher); } NLOG_INFO("Loaded name patterns:"); for (TQNamePatternMatcherList::iterator it = m_oQNamePatternMatcherList.begin(); it != m_oQNamePatternMatcherList.end(); ++it) { NLOG_INFO("\t%s[%d]%s", it->GetPrefix(), it->GetDeviceIdLen(), it->GetSuffix()); } /**********************************************************************/ return 1; };
void CSumiNodeTesterApp::Run() { //init if(!g_oUtils.APISendCreateSocket(m_stCfg.GetUdpLocalPort(), g_u8SerialMsgId, m_poBufferedSerialLink)) return; g_u8SerialMsgId++; //receive ACK or NACK CSimpleTimer oTimer(m_stCfg.GetUDPCreateSockTimedoutSec()*1000); int nRecvLen = 0; bool bNoReply = true; while(!oTimer.IsSignaling() && bNoReply) { if( !m_poBufferedSerialLink->IsLinkOpen() || !m_poBufferedSerialLink->HaveData( WAITUS ) ) { continue; } nRecvLen = m_poBufferedSerialLink->Read( g_pucRcvBuf, BUFSIZE ); //check if (nRecvLen <= 0) continue; if (nRecvLen < (int)sizeof(API_MSG_HDR)) { NLOG_ERR("FAILED TO READ MSG HEADER ON SERIAL LINK!"); break; } //process rsp for APISendCreateSocket API_MSG_HDR *pHdr = (API_MSG_HDR*)g_pucRcvBuf; if (!API_GET_IS_RSP_FLAG(pHdr)) { NLOG_WARN("Expected a response for APISendCreateSocket but received a request!"); continue; } switch(API_GET_MSG_CLASS(pHdr)) { case API_ACK: if(API_GET_MESSAGE_ID(pHdr) == (g_u8SerialMsgId - 1)) { NLOG_INFO("UDP PORT %d SUCCESSFULLY OPENED!", m_stCfg.GetUdpLocalPort()); bNoReply = false; } break; case API_NACK: if(API_GET_MESSAGE_ID(pHdr) != (g_u8SerialMsgId - 1)) { continue; } switch(API_GET_TYPE(pHdr)) { case API_UDP_PORT_ALREADY_IN_USE: NLOG_INFO("API_UDP_PORT_ALREADY_IN_USE, UDP port=%d!", m_stCfg.GetUdpLocalPort()); bNoReply = false; break; case API_MAX_SOCKETS_NO_REACHED: NLOG_ERR("API_MAX_SOCKETS_NO_REACHED!"); return; case API_COULD_NOT_CREATE_SOCKET: NLOG_ERR("API_COULD_NOT_CREATE_SOCKET UDP port=%d!", m_stCfg.GetUdpLocalPort()); return; default: NLOG_ERR("UNKNOWN NACK MSG TYPE: %d!", API_GET_TYPE(pHdr)); return; } break; default: NLOG_ERR("UNKNOWN MSG CLASS: %d!", API_GET_MSG_CLASS(pHdr)); return; } } if( bNoReply ) { NLOG_ERR("NO REPLY TO UDP_CREATE_SOCKET!"); return; } //process every received msg CSimpleTimer oUdpSendTimer(m_stCfg.GetUdpSendIntervalSec()* 1000); CSimpleTimer oUdpSentPollTimer(m_stCfg.GetUdpSentPollIntervalSec()*1000); CSimpleTimer oStatisticsTimer(300000); CSimpleTimer oSigFileCheckTimer(m_stCfg.GetSigFileCheckIntervalSec()*1000); while (!CApp::IsStop()) { TouchPidFile(g_pApp->m_szAppPidFile); //On Send UDP EVENT if( oUdpSendTimer.IsSignaling() ) { SendUdpData(); oUdpSendTimer.SetTimer(m_stCfg.GetUdpSendIntervalSec()* 1000); } //On Receive Data EVENT ProcessRcv(); //On Poll Sent UDP Msg EVENT if( oUdpSentPollTimer.IsSignaling()) { g_oSumiStats.PollSentUdpMsg(); oUdpSentPollTimer.SetTimer(m_stCfg.GetUdpSentPollIntervalSec()*1000); } //On Log Statistics EVENT if( oStatisticsTimer.IsSignaling() ) { g_oSumiStats.LogStatistics(); oStatisticsTimer.SetTimer(300000); } //On Check SIG File EVENT if( oSigFileCheckTimer.IsSignaling() ) { CSignalsMgr::Raise( SIGHUP ); oSigFileCheckTimer.SetTimer(m_stCfg.GetSigFileCheckIntervalSec()* 1000); } //On Signals Check EVENT CheckSignals(); } NLOG_INFO("Closing the socket..."); if( !g_oUtils.APISendDeleteSocket(m_stCfg.GetUdpLocalPort(), g_u8SerialMsgId, m_poBufferedSerialLink) ) return; g_u8SerialMsgId++; //receive ACK oTimer.SetTimer(UDP_DELETE_SOCK_TIMEDOUT_MS); nRecvLen = 0; bNoReply = true; while(!oTimer.IsSignaling() && bNoReply) { if( !m_poBufferedSerialLink->IsLinkOpen() || !m_poBufferedSerialLink->HaveData( WAITUS ) ) { continue; } nRecvLen = m_poBufferedSerialLink->Read( g_pucRcvBuf, BUFSIZE ); //check if (nRecvLen <= 0) continue; if (nRecvLen < (int)sizeof(API_MSG_HDR)) { NLOG_ERR("FAILED TO READ MSG HEADER ON SERIAL LINK!"); break; } //process rsp API_MSG_HDR *pHdr = (API_MSG_HDR*)g_pucRcvBuf; if (!API_GET_IS_RSP_FLAG(pHdr)) { NLOG_WARN("Expected a response for APISendDeleteSocket but received a request!"); continue; } switch(API_GET_MSG_CLASS(pHdr)) { case API_ACK: if(API_GET_MESSAGE_ID(pHdr) == (g_u8SerialMsgId - 1)) { NLOG_INFO("UDP PORT %d SUCCESSFULLY CLOSED!", m_stCfg.GetUdpLocalPort()); bNoReply = false; } break; case API_NACK: if(API_GET_MESSAGE_ID(pHdr) != (g_u8SerialMsgId - 1)) { continue; } switch(API_GET_TYPE(pHdr)) { case API_IVALID_DELETE_SOCKET: NLOG_WARN("API_INVALID_DELETE_SOCKET UDP port=%d!", m_stCfg.GetUdpLocalPort()); bNoReply = false; break; default: NLOG_ERR("UNKNOWN NACK MSG TYPE: %d!", API_GET_TYPE(pHdr)); return; } break; default: NLOG_ERR("UNKNOWN MSG CLASS: %d!", API_GET_MSG_CLASS(pHdr)); return; } } if( bNoReply ) { NLOG_ERR("NO REPLY TO UDP_CLOSE_SOCKET!"); return; } }
bool CTun::collectIp4Packet(IpPacket::IPv4* p_poPacket, ssize_t br) { uint16_t nIPHdrSize = p_poPacket->IHL() * 4; if (br < nIPHdrSize) { NLOG_WARN("CTun::CollectIp4Packet, [IP] header too small: expected(0x%04x), received(0x%04x)", nIPHdrSize, br); return false; } // verify ip header checksum uint16_t rcvChecksum = ntohs(p_poPacket->m_u16_Checksum); p_poPacket->m_u16_Checksum = 0; uint16_t expChecksum = IpPacket::Checksum((const uint8_t*)p_poPacket, nIPHdrSize); if (expChecksum != rcvChecksum) { NLOG_WARN("CTun::CollectIp4Packet, [IP] incorrect checksum: expected(0x%04x), received(0x%04x)", expChecksum, rcvChecksum); return false; } p_poPacket->m_u16_Checksum = htons(rcvChecksum); // verify packet length uint16_t rcvLen = ntohs(p_poPacket->m_u16_TotalLength); if (br != rcvLen) { NLOG_WARN("CTun::CollectIp4Packet, [IP] packet too small: expected(0x%04x), received(0x%04x)", rcvLen, br); } // verify checksum switch(p_poPacket->m_u8_Protocol) { case IPPROTO_ICMP: { rcvChecksum = ntohs(p_poPacket->m_oICMP_Payload.m_u16_Checksum); p_poPacket->m_oICMP_Payload.m_u16_Checksum = 0; expChecksum = IpPacket::Checksum((const uint8_t*)(&p_poPacket->m_oICMP_Payload), rcvLen - nIPHdrSize); if (expChecksum != rcvChecksum) { NLOG_WARN("CTun::CollectIp4Packet, [ICMP] incorrect checksum: expected(0x%04x), received(0x%04x)", expChecksum, rcvChecksum); return false; } p_poPacket->m_oICMP_Payload.m_u16_Checksum = htons(rcvChecksum); break; } case IPPROTO_UDP: { rcvChecksum = ntohs(p_poPacket->m_oUDP_Payload.m_u16_Checksum); // UDP checksum disabled - don't verify if (!rcvChecksum) break; Ip4UDPPseudoHdr oPHdr(p_poPacket); // pseudoheader checksum expChecksum = IpPacket::Checksum((uint8_t*)&oPHdr, sizeof (Ip4UDPPseudoHdr)); p_poPacket->m_oUDP_Payload.m_u16_Checksum = 0; expChecksum = IpPacket::Checksum((uint8_t*)&p_poPacket->m_oUDP_Payload, rcvLen - nIPHdrSize, expChecksum); if(!expChecksum ) expChecksum = 0xFFFF; if (expChecksum != rcvChecksum) { NLOG_WARN("CTun::CollectIp4Packet, [UDP] incorrect checksum: expected(0x%04x), received(0x%04x)", expChecksum, rcvChecksum); return false; } p_poPacket->m_oUDP_Payload.m_u16_Checksum = htons(rcvChecksum); break; } default:; } return true; }
//PROCESS bool CSumiNodeTesterApp::ProcessRcv() { //input data if( !m_poBufferedSerialLink->IsLinkOpen() || !m_poBufferedSerialLink->HaveData( WAITUS ) ) return false; //check int nRecvLen = m_poBufferedSerialLink->Read( g_pucRcvBuf, BUFSIZE ); if (nRecvLen <= 0) return false; if (nRecvLen < (int)sizeof(API_MSG_HDR)) { NLOG_ERR("FAILED TO READ MSG HEADER ON SERIAL LINK!"); return false; } //process rsp API_MSG_HDR *pHdr = (API_MSG_HDR*)g_pucRcvBuf; if (API_GET_IS_RSP_FLAG(pHdr)) { switch(API_GET_MSG_CLASS(pHdr)) { case API_ACK: NLOG_INFO("RECV ACK msg_id = %u", API_GET_MESSAGE_ID(pHdr)); g_oSumiStats.MarkSentUdpMsgAsAcked(API_GET_MESSAGE_ID(pHdr)); return true; case API_NACK: switch(API_GET_TYPE(pHdr)) { case API_INVALID_SIZE: NLOG_ERR("RECV NACK(API_INVALID_SIZE) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; case API_UDP_ERR_INTERNAL: NLOG_INFO("RECV NACK(API_UDP_ERR_INTERNAL) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; case API_UDP_ERR_DEV_NOT_JOINED: NLOG_INFO("RECV NACK(API_UDP_ERR_DEV_NOT_JOINED) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; case API_UDP_ERR_INVALID_SOCKET: NLOG_INFO("RECV NACK(API_UDP_ERR_INVALID_SOCKET) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; case API_UDP_ERR_NO_MEMORY: NLOG_INFO("RECV NACK(API_UDP_ERR_NO_MEMORY) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; case API_UDP_ERR_ND_NOT_READY: NLOG_INFO("RECV NACK(API_UDP_ERR_ND_NOT_READY) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; default: NLOG_INFO("RECV NACK(UNKNOWN) for msg_id = %u", API_GET_MESSAGE_ID(pHdr)); break; } g_oSumiStats.RemoveSentUdpMsg(API_GET_MESSAGE_ID(pHdr)); return false; default: NLOG_ERR("RECV OTHER RESPONSE, MSG CLASS= %d!", API_GET_MSG_CLASS(pHdr)); return false; } } //process request from RM switch(API_GET_MSG_CLASS(pHdr)) { case UDP_SPECIFIC: { if (API_GET_TYPE(pHdr) != UDP_RECEIVE_DATAGRAM) break; //check for serial duplicates if( g_bIsFirstDatagramRecv ) { g_u8RecvSerialMsgId = API_GET_MESSAGE_ID(pHdr); g_bIsFirstDatagramRecv = false; } else if( API_GET_MESSAGE_ID(pHdr) == g_u8RecvSerialMsgId ) { NLOG_WARN("UDP_RECEIVE_DATAGRAM already read! Ignoring it..."); return false; } else { g_u8RecvSerialMsgId = API_GET_MESSAGE_ID(pHdr); } // UDP_RECV_DATAGRAM_PYLD* pRcvUdpDatagram = (UDP_RECV_DATAGRAM_PYLD*)((unsigned char*)pHdr + sizeof(API_MSG_HDR)); UDP_PYLD_ID *pUDPPyldId = (UDP_PYLD_ID*)((unsigned char*)pHdr + sizeof(API_MSG_HDR) + sizeof(UDP_RECV_DATAGRAM_PYLD)); unsigned int unUdpId = GET_UDP_PYLD_ID(pUDPPyldId); //log msg NLOG_INFO("Received data: addr=%s:%d, len=%d, UDP_ID=%d", GetHex(pRcvUdpDatagram->m_au8SrcIpv6, 16), UDP_RECV_DATAGRAM_GET_SRC_PORT(pRcvUdpDatagram), nRecvLen - sizeof(API_MSG_HDR) - sizeof(UDP_RECV_DATAGRAM_PYLD), unUdpId); memset(g_aucLogBuf,0,sizeof(g_aucLogBuf)); Bin2Hex((char*)g_aucLogBuf, sizeof(g_aucLogBuf), (char*)pRcvUdpDatagram + sizeof(UDP_RECV_DATAGRAM_PYLD), nRecvLen - sizeof(API_MSG_HDR)- sizeof(UDP_RECV_DATAGRAM_PYLD)); NLOG_INFO("Datagram payload: %s", g_aucLogBuf); // g_oSumiStats.MarkSentUdpMsgAsResponded( unUdpId ); //send ack if (!g_oUtils.SendACK(API_GET_MESSAGE_ID(pHdr), m_poBufferedSerialLink)) return false; } break; case API_DEBUG: { if (API_GET_TYPE(pHdr) != API_PRINT_LOG) break; if( API_GET_DATA_SIZE(pHdr) >= sizeof(g_aucLogBuf) ) { NLOG_ERR("LOG BUFFER TOO SMALL! Log buff=%d, API DATA SIZE=%d", sizeof(g_aucLogBuf), API_GET_DATA_SIZE(pHdr)); return false; } memcpy(g_aucLogBuf, g_pucRcvBuf + sizeof(API_MSG_HDR), API_GET_DATA_SIZE(pHdr)); g_aucLogBuf[API_GET_DATA_SIZE(pHdr)]='\0'; LOG("Log on dev: %s",g_aucLogBuf); } break; case STACK_SPECIFIC: { switch(API_GET_TYPE(pHdr)) { case NOTIFY_JOIN: { STACK_NOTIFY_JOIN *pNotifyJoin = (STACK_NOTIFY_JOIN*)((unsigned char*)pHdr + sizeof(API_MSG_HDR)); switch(pNotifyJoin->m_u8Status) { case MAC_IDLE_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= MAC_IDLE_STATE"); break; case ENERGY_DETECT_SCANNING_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= ENERGY_DETECT_SCANNING_STATE"); break; case ACTIVE_SCANNING_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= ACTIVE_SCANNING_STATE"); break; case SECURITY_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= SECURITY_STATE"); break; case ASSOCIATING_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= ASSOCIATING_STATE"); break; case ASSOCIATED_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= ASSOCIATED_STATE"); break; case ORPHAN_STATE: NLOG_INFO("Recv NOTIFY_JOIN, status= ORPHAN_STATE"); break; default: NLOG_WARN("Recv NOTIFY_JOIN, status = %u, UNKNOWN msg_id=%u!", pNotifyJoin->m_u8Status, API_GET_MESSAGE_ID(pHdr)); break; } //send ack if (!g_oUtils.SendACK(API_GET_MESSAGE_ID(pHdr), m_poBufferedSerialLink)) return false; } break; default: NLOG_ERR("UNKNOWN STACK_SPECIFIC TYPE!"); break; } } break; default: NLOG_WARN("RECV OTHER REQUEST MSG CLASS = %d", API_GET_MSG_CLASS(pHdr)); return false; } return true; }
bool CIPGRegUpdCmd::ProcessMsg(CMgmtPOption::OptionIPGatewayInfoData **p_ppOpData1, std::list<CMgmtPOption::OptionIPRoutesListData> &p_rawRouteInfo, CMgmtPOption::OptionKeepAliveIntervalData **p_ppOpData2) { CMgmtPOptionList& optionList = m_rMsg.OptionListGet(); if (!optionList.size()) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: no option list, skip processing msg = %s", MsgToStr(m_rMsg).c_str()); return false; } bool msgHasIpgInf = false; bool msgHasKA = false; bool msgHasTunn = false; for (CMgmtPOptionList::iterator j = optionList.begin(); j != optionList.end(); ++j) { CMgmtPOption::Ptr &optPtr = *j; switch(optPtr->GetType()) { case CMgmtPOption::OPTION_IPG_INFO: { msgHasIpgInf = true; optPtr->GetData<CMgmtPOption::OptionIPGatewayInfoData>(p_ppOpData1); if ((*p_ppOpData1)->m_IPGAddrIPv4 == 0 || IsNULLIPv6((*p_ppOpData1)->m_szIPGAddrIPv6)) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: invalid IPG's public_info: IPv4=%s, IPv6=%s, skip processing msg = %s", IPv4ToStr((*p_ppOpData1)->m_IPGAddrIPv4).c_str(), IPv6ToStr((*p_ppOpData1)->m_szIPGAddrIPv6).c_str(), MsgToStr(m_rMsg).c_str()); return false; } break; } case CMgmtPOption::OPTION_IPV6_TUN_LIST: { if(msgHasTunn == true) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: too many tunnels options!"); return false; } CMgmtPOption::OptionIPv6TunnelListData *pOpData; optPtr->GetData<CMgmtPOption::OptionIPv6TunnelListData>(&pOpData); if (pOpData->m_FARAddrIPv4 != 0 || !IsNULLIPv6(pOpData->m_szFARAddrIPv6)) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: FAR ipv4 || ipv6 should be zeroed"); return false; } msgHasTunn = true; break; } case CMgmtPOption::OPTION_KEEPALIVE_INTERVAL: { msgHasKA = true; optPtr->GetData<CMgmtPOption::OptionKeepAliveIntervalData>(p_ppOpData2); break; } case CMgmtPOption::OPTION_IPROUTES_LIST: { CMgmtPOption::OptionIPRoutesListData *pOpData = (CMgmtPOption::OptionIPRoutesListData*)optPtr->GetRawData(); if (pOpData->m_NetType != 2 || pOpData->m_NetPrefixLen > 128 || IsNULLIPv6(pOpData->m_NetPrefix) || IsNULLIPv6(pOpData->m_GatewayAddr)) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: m_NetType != 2 || m_NetPrefixLen > 128 || m_NetPrefix || m_GatewayAddr should not be zeroed"); return false; } p_rawRouteInfo.push_back(*pOpData); break; } default: NLOG_WARN("[IPGRegUpdCmd:ProcessMsg]: invalid option=%d, msg = %s", optPtr->GetType(), MsgToStr(m_rMsg).c_str()); } } if (!msgHasKA && !msgHasIpgInf) { NLOG_ERR("[IPGRegUpdCmd:ProcessMsg]: less option list, skip processing msg = %s", MsgToStr(m_rMsg).c_str()); return false; } return true; }