Пример #1
0
// (pat 9-2014) Print out peering messages.  We triage the messages depending on the log level.
// INFO level - Handover messages only.
// DEBUG level - all messages.
static void logMessage(const char*sendOrRecv, const struct sockaddr_in* peer, const char *message)
{
	const char *arg1 = getPeeringMsgArg1(message);
	if (0 == strncmp(arg1,"HANDOVER",8)) {
		LOG(INFO) << "Peering "<<sendOrRecv <<LOGVAR2("peer",sockaddr2string(peer,true)) <<LOGVAR(message);
		// We used to watch everything except REQ NEI messages: if (strncmp(message,"REQ NEI",7))
		const char *eol = strchr(message,'\n');
		WATCHLEVEL(INFO," Peering "<<sendOrRecv <<LOGVAR2("peer",sockaddr2string(peer,true))
				<<LOGVAR2("message",string(message,eol?eol-message:strlen(message))));	// first line of message; they used to be long.
	} else {
		// At DEBUG level log all messages.
		LOG(DEBUG) << "Peering "<<sendOrRecv<<LOGVAR2("peer",sockaddr2string(peer,true)) <<LOGVAR(message);
	}

}
PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(IPv4Address ipAddr)
{
	LOG_DEBUG("Searching all live devices...");
	for(std::vector<PcapLiveDevice*>::iterator devIter = m_LiveDeviceList.begin(); devIter != m_LiveDeviceList.end(); devIter++)
	{
		LOG_DEBUG("Searching device '%s'. Searching all addresses...", (*devIter)->m_Name);
		for(std::vector<pcap_addr_t>::iterator addrIter = (*devIter)->m_Addresses.begin(); addrIter != (*devIter)->m_Addresses.end(); addrIter++)
		{
			if (LoggerPP::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter->addr != NULL)
			{
				char addrAsString[INET6_ADDRSTRLEN];
				sockaddr2string(addrIter->addr, addrAsString);
				LOG_DEBUG("Searching address %s", addrAsString);
			}

			in_addr* currAddr = sockaddr2in_addr(addrIter->addr);
			if (currAddr == NULL)
			{
				LOG_DEBUG("Address is NULL");
				continue;
			}

			if (currAddr->s_addr == ipAddr.toInAddr()->s_addr)
			{
				LOG_DEBUG("Found matched address!");
				return (*devIter);
			}
		}
	}

	return NULL;
}
Пример #3
0
void PeerInterface::process(const struct sockaddr_in* peer, const char* message)
{
	logMessage("receive",peer,message);

	// neighbor message?
	if (strncmp(message+3," NEIGHBOR_PARAMS",16)==0)
		return processNeighborParams(peer,message);

	// must be handover related
	string peerString = sockaddr2string(peer, true);
	LOG(INFO) << "received from"<<LOGVAR2("peer",peerString) <<LOGVAR(message);

	// Initial inbound handover request?
	if (strncmp(message,"REQ HANDOVER ",13)==0)
		return processHandoverRequest(peer,message);

	// Handover response? ("Handover Accept" in the ladder.)
	if (strncmp(message,"RSP HANDOVER ",13)==0)
		return processHandoverResponse(peer,message);

	// IND HANDOVER_COMPLETE
	if (strncmp(message,"IND HANDOVER_COMPLETE ", 22)==0)
		return processHandoverComplete(peer,message);

	// IND HANDOVER_FAILURE
	if (strncmp(message,"IND HANDOVER_FAILURE ", 21)==0)
		return processHandoverFailure(peer,message);

	// Other handover messages go into the FIFO map.
	// (pat) It is an ACK message, and we need to queue it because the 'senduntilack' is running in a different thread.
	// FIXME -- We need something here to spot malformed messages.
	unsigned transactionID;
	sscanf(message, "%*s %*s %u", &transactionID);
	mFIFOMap.writeFIFO(transactionID,message);
}
Пример #4
0
IPv4Address PcapLiveDevice::getIPv4Address()
{
	for(std::vector<pcap_addr_t>::iterator addrIter = m_Addresses.begin(); addrIter != m_Addresses.end(); addrIter++)
	{
		if (LoggerPP::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter->addr != NULL)
		{
			char addrAsString[INET6_ADDRSTRLEN];
			sockaddr2string(addrIter->addr, addrAsString);
			LOG_DEBUG("Searching address %s", addrAsString);
		}

		in_addr* currAddr = sockaddr2in_addr(addrIter->addr);
		if (currAddr == NULL)
		{
			LOG_DEBUG("Address is NULL");
			continue;
		}

		return IPv4Address(currAddr);
	}

	return IPv4Address::Zero;
}
PcapLiveDevice* PcapLiveDeviceList::getPcapLiveDeviceByIp(IPv6Address ip6Addr)
{
	LOG_DEBUG("Searching all live devices...");
	for(std::vector<PcapLiveDevice*>::iterator devIter = m_LiveDeviceList.begin(); devIter != m_LiveDeviceList.end(); devIter++)
	{
		LOG_DEBUG("Searching device '%s'. Searching all addresses...", (*devIter)->m_Name);
		for(std::vector<pcap_addr_t>::iterator addrIter = (*devIter)->m_Addresses.begin(); addrIter != (*devIter)->m_Addresses.end(); addrIter++)
		{
			if (LoggerPP::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && addrIter->addr != NULL)
			{
				char addrAsString[INET6_ADDRSTRLEN];
				sockaddr2string(addrIter->addr, addrAsString);
				LOG_DEBUG("Searching address %s", addrAsString);
			}

			in6_addr* currAddr = sockaddr2in6_addr(addrIter->addr);
			if (currAddr == NULL)
			{
				LOG_DEBUG("Address is NULL");
				continue;
			}

			uint8_t* addrAsArr; size_t addrLen;
			ip6Addr.copyTo(&addrAsArr, addrLen);
			if (memcmp(currAddr, addrAsArr, sizeof(struct in6_addr)) == 0)
			{
				LOG_DEBUG("Found matched address!");
				return (*devIter);
			}

			delete [] addrAsArr;
		}
	}

	return NULL;
}
Пример #6
0
// pats TODO: We should check for conflicts when we start up.
// pats TODO: Check for more than 31 ARFCNs and report.
// pats TODO: We should check for ARFCN+BSIC conflicts among the neighbors.  That implies sucking the whole neighbor table in,
// but dont worry about now it because the whole thing should move to SR imho.
void PeerInterface::processNeighborParams(const struct sockaddr_in* peer, const char* message)
{
	try {

	// Create a unique id so we can tell if we send a message to ourself.
	static uint32_t btsid = 0;
	while (btsid == 0) { btsid = (uint32_t) random(); }

	// (pat) This is the original format, which I now call version 1.
	static const char rspFormatV1[] = "RSP NEIGHBOR_PARAMS %u %u";      // C0 BSIC
	// (pat) This is the 3-2014 format.  Extra args are ignored by older versions of OpenBTS.
	//static const char rspFormat[] = "RSP NEIGHBOR_PARAMS %u %u %u %d %u %u %u";  // C0 BSIC uniqueID noise numArfcns tchavail tchtotal

	LOG(DEBUG) << "got message " << message;
	if (0 == strncmp(message,"REQ ",4)) {
		// REQ?  Send a RSP.
		char rsp[150];
		if (! strchr(message,'=')) {
			// Send version 1.
			snprintf(rsp, sizeof(rsp), rspFormatV1, gTRX.C0(), gBTS.BSIC());
		} else {
			// Send version 2.
			int myNoise = gTRX.ARFCN(0)->getNoiseLevel();
			unsigned tchTotal = gBTS.TCHTotal();
			unsigned tchAvail = tchTotal - gBTS.TCHActive();
			snprintf(rsp, sizeof(rsp), "RSP NEIGHBOR_PARAMS V=2 C0=%u BSIC=%u btsid=%u noise=%d arfcns=%d TchAvail=%u TchTotal=%u",
					gTRX.C0(), gBTS.BSIC(), btsid, myNoise, (int)gConfig.getNum("GSM.Radio.ARFCNs"), tchAvail, tchTotal);
			sendMessage(peer,rsp);
		}
		return;
	}

	if (0 == strncmp(message,"RSP ",4)) {
		// RSP?  Digest it.
		NeighborEntry newentry;

		if (! strchr(message,'=')) {
			// Version 1 message.
			int r = sscanf(message, rspFormatV1, &newentry.mC0, &newentry.mBSIC);
			if (r != 2) {
				logAlert(format("badly formatted peering message: %s",message));
				return;
			}
		} else {
			SimpleKeyValue keys;
			keys.addItems(message + sizeof("RSP NEIGHBOR_PARAMS"));	// sizeof is +1 which is ok - we are skipping the initial space.

			{	bool valid;
				unsigned neighborID = keys.getNum("btsid",valid);
				if (valid && neighborID == btsid) {
					LOG(ERR) << "BTS is in its own GSM.Neighbors list.";
					return;
				}
			}

			newentry.mC0 = keys.getNumOrBust("C0");
			newentry.mBSIC = keys.getNumOrBust("BSIC");
			newentry.mNoise = keys.getNumOrBust("noise");
			newentry.mNumArfcns = keys.getNumOrBust("arfcns");
			newentry.mTchAvail = keys.getNumOrBust("TchAvail");
			newentry.mTchTotal = keys.getNumOrBust("TchTotal");
		}

		newentry.mIPAddress = sockaddr2string(peer, false);
		if (newentry.mIPAddress.size() == 0) {
			LOG(ERR) << "cannot parse peer socket address for"<<LOGVAR2("C0",newentry.mC0)<<LOGVAR2("BSIC",newentry.mBSIC);
			return;
		}


		// Did the neighbor list change?
		bool change = gNeighborTable.ntAddInfo(newentry);
		// no change includes unsolicited RSP NEIGHBOR_PARAMS.  drop it.
		if (!change) return;

		// It there a BCC conflict?
		int ourBSIC = gBTS.BSIC();
		if (newentry.mC0 == (int)gTRX.C0()) {
			if (newentry.mBSIC == ourBSIC) {
				logAlert(format("neighbor with matching ARFCN.C0 + BSIC [Base Station Identifier] codes: C0=%d BSIC=%u",newentry.mC0,newentry.mBSIC));
			} else {
				// Two BTS on the same ARFCN close enough to be neighbors, which is probably a bad idea, but legal.
				// Is it worth an ALERT?
				LOG(WARNING) << format("neighbor with matching ARFCN.C0 but different BSIC [Base Station Identifier] code: C0=%d, BSIC=%u, my BSIC=%u",
						newentry.mC0,newentry.mBSIC,gTRX.C0());
			}
		}

		// 3-2014: Warn for overlapping ARFCN use.  Fixes ticket #857
		int myC0 = gTRX.C0();
		int myCEnd = myC0 + gConfig.getNum("GSM.Radio.ARFCNs") - 1;
		int neighborCEnd = newentry.mC0 + newentry.mNumArfcns - 1;
		bool overlap = myC0 <= neighborCEnd && myCEnd >= (int) newentry.mC0;
		if (overlap) {
			LOG(WARNING) << format("neighbor IP=%s BSIC=%d ARFCNs=%u to %d overlaps with this BTS ARFCNs=%d to %d",
					newentry.mIPAddress.c_str(), newentry.mBSIC, newentry.mC0, neighborCEnd, myC0, myCEnd);
		}

		// Is there an NCC conflict?
		// (pat) ARFCN-C0 (the one carrying BCCH) and BSIC consisting of NCC (Network Color Code) and BCC. (Base station Color Code)
		int neighborNCC = newentry.mBSIC >> 3;
		int NCCMaskBit = 1 << neighborNCC;
		int ourNCCMask = gConfig.getNum("GSM.CellSelection.NCCsPermitted");
		ourNCCMask |= 1 << gConfig.getNum("GSM.Identity.BSIC.NCC");
		if ((NCCMaskBit & ourNCCMask) == 0) { 
			//LOG(ALERT) << "neighbor with NCC " << neighborNCC << " not in NCCsPermitted";
			logAlert(format("neighbor with NCC=%u not in NCCsPermitted",neighborNCC));
		}
		// There was a change, so regenerate the beacon
		gBTS.regenerateBeacon();
		return;
	}

	LOG(ALERT) << "unrecognized Peering message: " << message;

	} catch (SimpleKeyValueException &e) {
Пример #7
0
PcapLiveDevice::PcapLiveDevice(pcap_if_t* pInterface, bool calculateMTU, bool calculateMacAddress) : IPcapDevice(),
		m_MacAddress("")
{

	m_Name = NULL;
	m_Description = NULL;
	m_DeviceMtu = 0;

	m_IsLoopback = (pInterface->flags & 0x1) == PCAP_IF_LOOPBACK;

	int strLength = strlen(pInterface->name)+1;
	m_Name = new char[strLength];
	strncpy((char*)m_Name, pInterface->name, strLength);

	strLength = 1;
	if (pInterface->description != NULL)
		strLength += strlen(pInterface->description);
	m_Description = new char[strLength];
	if (pInterface->description != NULL)
		strncpy((char*)m_Description, pInterface->description, strLength);
	else
		strncpy((char*)m_Description, "", strLength);
	LOG_DEBUG("Added live device: name=%s; desc=%s", m_Name, m_Description);
	LOG_DEBUG("   Addresses:");
	while (pInterface->addresses != NULL)
	{
		m_Addresses.insert(m_Addresses.end(), *(pInterface->addresses));
		pInterface->addresses = pInterface->addresses->next;
		if (LoggerPP::getInstance().isDebugEnabled(PcapLogModuleLiveDevice) && pInterface->addresses != NULL && pInterface->addresses->addr != NULL)
		{
			char addrAsString[INET6_ADDRSTRLEN];
			sockaddr2string(pInterface->addresses->addr, addrAsString);
			LOG_DEBUG("      %s", addrAsString);
		}
	}

	if (calculateMTU)
	{
		setDeviceMtu();
		LOG_DEBUG("   MTU: %d", m_DeviceMtu);
	}

	//init all other members
	m_CaptureThreadStarted = false;
	m_StatsThreadStarted = false;  m_IsLoopback = false;
	m_StopThread = false;
	m_CaptureThread = new PcapThread();
	m_StatsThread = new PcapThread();
	memset(m_CaptureThread, 0, sizeof(PcapThread));
	memset(m_StatsThread, 0, sizeof(PcapThread));
	m_cbOnPacketArrives = NULL;
	m_cbOnStatsUpdate = NULL;
	m_IntervalToUpdateStats = 0;
	m_cbOnPacketArrivesUserCookie = NULL;
	m_cbOnStatsUpdateUserCookie = NULL;
	m_CaptureCallbackMode = true;
	m_CapturedPackets = NULL;
	if (calculateMacAddress)
	{
		setDeviceMacAddress();
		if (m_MacAddress.isValid())
			LOG_DEBUG("   MAC addr: %s", m_MacAddress.toString().c_str());
	}
}