示例#1
0
void SipTcpData::processData(u_int32_t ip_src, u_int32_t ip_dst,
			     u_int16_t port_src, u_int16_t port_dst,
			     TcpReassemblyData *data,
			     u_char *ethHeader, u_int32_t ethHeaderLength,
			     u_int16_t handle_index, int dlt, int sensor_id, u_int32_t sensor_ip,
			     void *uData, TcpReassemblyLink *reassemblyLink,
			     bool debugSave) {
	++this->counterProcessData;
	if(debugSave) {
		cout << "### SipData::processData " << this->counterProcessData << endl;
	}
	u_int64_t cache_time = 0;
	for(size_t i_data = 0; i_data < data->data.size(); i_data++) {
		TcpReassemblyDataItem *dataItem = &data->data[i_data];
		list<d_u_int32_t> sip_offsets;
		if(!dataItem->getData() ||
		   !TcpReassemblySip::checkSip(dataItem->getData(), dataItem->getDatalen(), true, &sip_offsets)) {
			continue;
		}
		for(list<d_u_int32_t>::iterator iter_sip_offset = sip_offsets.begin(); iter_sip_offset != sip_offsets.end(); iter_sip_offset++) {
			cache_time = dataItem->getTime().tv_sec * 1000 + dataItem->getTime().tv_usec / 1000;
			string md5_data = GetDataMD5(dataItem->getData() + (*iter_sip_offset)[0], (*iter_sip_offset)[1]);
			Cache_id cache_id(ip_src, ip_dst, port_src, port_dst);
			map<Cache_id, Cache_data*>::iterator cache_iterator = cache.find(cache_id);
			if(cache_iterator != cache.end()) {
				Cache_data *cache_data = cache_iterator->second;
				map<string, u_int64_t>::iterator cache_data_iterator = cache_data->data.find(md5_data);
				if(cache_data_iterator != cache_data->data.end()) {
					if(cache_data_iterator->second + 100 > (u_int64_t)cache_time) {
						cache_data_iterator->second = cache_time;
						continue;
					}
				} else {
					cache_data->data[md5_data] = cache_time;
				}
			} else {
				Cache_data *cache_data = new Cache_data;
				cache_data->data[md5_data] = cache_time;
				cache[cache_id] = cache_data;
			}
			if(debugSave) {
				cout << "###"
				     << fixed
				     << setw(15) << inet_ntostring(htonl(ip_src))
				     << " / "
				     << setw(5) << port_src
				     << (dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? " --> " : " <-- ")
				     << setw(15) << inet_ntostring(htonl(ip_dst))
				     << " / "
				     << setw(5) << port_dst
				     << "  len: " << setw(4) << (*iter_sip_offset)[1];
				u_int32_t ack = dataItem->getAck();
				if(ack) {
					cout << "  ack: " << setw(5) << ack;
				}
				cout << endl;
			}
			pcap_pkthdr *tcpHeader;
			u_char *tcpPacket;
			u_int32_t _ip_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_src : ip_dst;
			u_int32_t _ip_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_dst : ip_src;
			u_int16_t _port_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_src : port_dst;
			u_int16_t _port_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_dst : port_src;
			createSimpleTcpDataPacket(ethHeaderLength, &tcpHeader,  &tcpPacket,
						  ethHeader, dataItem->getData() + (*iter_sip_offset)[0], (*iter_sip_offset)[1],
						  _ip_src, _ip_dst, _port_src, _port_dst,
						  dataItem->getAck(), dataItem->getTime().tv_sec, dataItem->getTime().tv_usec);
			unsigned dataOffset = ethHeaderLength + sizeof(iphdr2) + ((tcphdr2*)(tcpPacket + ethHeaderLength + sizeof(iphdr2)))->doff * 4;
			if(uData) {
				packet_s_process *packetS = PACKET_S_PROCESS_SIP_CREATE();
				#if USE_PACKET_NUMBER
				packetS->packet_number = 0;
				#endif
				packetS->saddr = _ip_src;
				packetS->source = _port_src;
				packetS->daddr = _ip_dst; 
				packetS->dest = _port_dst;
				packetS->datalen = (*iter_sip_offset)[1]; 
				packetS->dataoffset = dataOffset;
				packetS->handle_index = handle_index; 
				packetS->header_pt = tcpHeader;
				packetS->packet = tcpPacket; 
				packetS->_packet_alloc = true; 
				packetS->istcp = 2;
				packetS->header_ip_offset = ethHeaderLength; 
				packetS->block_store = NULL; 
				packetS->block_store_index =  0; 
				packetS->dlt = dlt; 
				packetS->sensor_id_u = (u_int16_t)sensor_id;
				packetS->sensor_ip = sensor_ip;
				packetS->is_ssl = false;
				extern int opt_skinny;
				extern char *sipportmatrix;
				packetS->is_skinny = opt_skinny && (_port_src == 2000 || _port_dst == 2000);
				packetS->is_need_sip_process = sipportmatrix[_port_src] || sipportmatrix[_port_dst] ||
							       packetS->is_skinny;
				packetS->init2();
				((PreProcessPacket*)uData)->process_parseSipDataExt(&packetS);
			} else {
				preProcessPacket[PreProcessPacket::ppt_extend]->push_packet(
						true, 0, _ip_src, _port_src, _ip_dst, _port_dst, 
						(char*)(tcpPacket + dataOffset), (*iter_sip_offset)[1], dataOffset,
						handle_index, tcpHeader, tcpPacket, true, 
						2, (iphdr2*)(tcpPacket + ethHeaderLength),
						NULL, 0, dlt, sensor_id, sensor_ip,
						false);
			}
		}
	}
	delete data;
	cleanupCache(cache_time);
}
示例#2
0
void SslData::processData(u_int32_t ip_src, u_int32_t ip_dst,
			  u_int16_t port_src, u_int16_t port_dst,
			  TcpReassemblyData *data,
			  u_char *ethHeader, u_int32_t ethHeaderLength,
			  pcap_t *handle, int dlt, int sensor_id,
			  TcpReassemblyLink *reassemblyLink,
			  bool debugSave) {
	++this->counterProcessData;
	if(debugSave) {
		cout << "### SslData::processData " << this->counterProcessData << endl;
	}
	for(size_t i_data = 0; i_data < data->data.size(); i_data++) {
		TcpReassemblyDataItem *dataItem = &data->data[i_data];
		if(!dataItem->getData()) {
			continue;
		}
		if(debugSave) {
			cout << "###"
			     << fixed
			     << setw(15) << inet_ntostring(htonl(ip_src))
			     << " / "
			     << setw(5) << port_src
			     << (dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? " --> " : " <-- ")
			     << setw(15) << inet_ntostring(htonl(ip_dst))
			     << " / "
			     << setw(5) << port_dst
			     << "  len: " << setw(4) << dataItem->getDatalen();
			u_int32_t ack = dataItem->getAck();
			if(ack) {
				cout << "  ack: " << setw(5) << ack;
			}
			cout << endl;
		}
		for(int pass = 0; pass < 2; pass++) {
			u_char *ssl_data;
			u_int32_t ssl_datalen;
			bool alloc_ssl_data = false;
			if(reassemblyLink->getRemainData(dataItem->getDirection())) {
				ssl_datalen = reassemblyLink->getRemainDataLength(dataItem->getDirection()) + dataItem->getDatalen();
				ssl_data = new FILE_LINE u_char[ssl_datalen];
				memcpy(ssl_data, reassemblyLink->getRemainData(dataItem->getDirection()), reassemblyLink->getRemainDataLength(dataItem->getDirection()));
				memcpy(ssl_data + reassemblyLink->getRemainDataLength(dataItem->getDirection()), dataItem->getData(), dataItem->getDatalen());
				alloc_ssl_data = true;
			} else {
				ssl_data = dataItem->getData();
				ssl_datalen = dataItem->getDatalen();
			}
			u_int32_t ssl_data_offset = 0;
			while(ssl_data_offset < ssl_datalen &&
			      ssl_datalen - ssl_data_offset >= 5) {
				SslHeader header(ssl_data + ssl_data_offset, ssl_datalen - ssl_data_offset);
				if(header.isOk() && header.length && (u_int32_t)header.length + header.getDataOffsetLength() <= ssl_datalen - ssl_data_offset) {
					if(debugSave) {
						cout << "SSL HEADER "
						     << "content type: " << (int)header.content_type << " / "
						     << "version: " << hex << header.version << dec << " / "
						     << "length: " << header.length
						     << endl;
					}
					u_int32_t _ip_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_src : ip_dst;
					u_int32_t _ip_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_dst : ip_src;
					u_int16_t _port_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_src : port_dst;
					u_int16_t _port_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_dst : port_src;
					vector<string> rslt_decrypt = decrypt_ssl((char*)(ssl_data + ssl_data_offset), header.length + header.getDataOffsetLength(), htonl(_ip_src), htonl(_ip_dst), _port_src, _port_dst);
					for(size_t i = 0; i < rslt_decrypt.size(); i++) {
						if(debugSave) {
							string out(rslt_decrypt[i], 0,100);
							std::replace( out.begin(), out.end(), '\n', ' ');
							std::replace( out.begin(), out.end(), '\r', ' ');
							    
							unsigned long s_addr = _ip_src;
							unsigned long d_addr = _ip_dst;
							char src[INET_ADDRSTRLEN];
							char dst[INET_ADDRSTRLEN];
							inet_ntop(AF_INET, &s_addr, src, INET_ADDRSTRLEN);
							inet_ntop(AF_INET, &d_addr, dst, INET_ADDRSTRLEN);
					       
						       
							if(out.length()) {
								cout << "TS: " << dataItem->getTime().tv_sec << "." << dataItem->getTime().tv_usec << " " << src << " -> " << dst << " SIP " << rslt_decrypt[i].length() << " " << out << endl;
							}

							cout << "DECRYPT DATA: " << rslt_decrypt[i] << endl;
						}
						if(sverb.ssldecode) {
							cout << rslt_decrypt[i];
						}
						if(!ethHeader || !ethHeaderLength) {
							continue;
						}
						pcap_pkthdr *udpHeader;
						u_char *udpPacket;
						createSimpleUdpDataPacket(ethHeaderLength, &udpHeader,  &udpPacket,
									  ethHeader, (u_char*)rslt_decrypt[i].c_str(), rslt_decrypt[i].size(),
									  _ip_src, _ip_dst, _port_src, _port_dst,
									  dataItem->getTime().tv_sec, dataItem->getTime().tv_usec);
						int was_rtp = 0;
						int voippacket = 0;
						if(preProcessPacket) {
							preProcessPacket->push(true, 0, _ip_src, _port_src, _ip_dst, _port_dst, 
									       (char*)(udpPacket + ethHeaderLength + sizeof(iphdr2) + sizeof(udphdr2)), rslt_decrypt[i].size(), ethHeaderLength + sizeof(iphdr2) + sizeof(udphdr2),
									       handle, udpHeader, udpPacket, true, 
									       false, (iphdr2*)(udpPacket + ethHeaderLength), 1,
									       NULL, 0, dlt, sensor_id);
						} else {
							process_packet(true, 0, _ip_src, _port_src, _ip_dst, _port_dst, 
								       (char*)rslt_decrypt[i].c_str(), rslt_decrypt[i].size(), ethHeaderLength + sizeof(iphdr2) + sizeof(udphdr2),
								       handle, udpHeader, udpPacket, 
								       false, &was_rtp, (iphdr2*)(udpPacket + ethHeaderLength), &voippacket, 1,
								       NULL, 0, dlt, sensor_id);
							delete [] udpPacket;
						}
						delete udpHeader;
					}
					ssl_data_offset += header.length + header.getDataOffsetLength();
				} else {
					break;
				}
			}
			if(pass == 0) {
				bool ok = false;
				if(reassemblyLink->getRemainDataLength(dataItem->getDirection()) &&
				   !ssl_data_offset &&
				   _checkOkSslData(dataItem->getData(), dataItem->getDatalen())) {
					// next pass with ignore remainData
					reassemblyLink->clearRemainData(dataItem->getDirection());
					if(debugSave) {
						cout << "SKIP REMAIN DATA" << endl;
					}
				} else {
					if(ssl_data_offset < ssl_datalen) {
						reassemblyLink->setRemainData(ssl_data + ssl_data_offset, ssl_datalen - ssl_data_offset, dataItem->getDirection());
						if(debugSave) {
							cout << "REMAIN DATA LENGTH: " << ssl_datalen - ssl_data_offset << endl;
						}
					} else {
						reassemblyLink->clearRemainData(dataItem->getDirection());
					}
					ok = true;
				}
				if(alloc_ssl_data) {
					delete [] ssl_data;
				}
				if(ok) {
					break;
				}
			}
		}
	}
	delete data;
}
示例#3
0
void WebrtcData::processData(u_int32_t ip_src, u_int32_t ip_dst,
			     u_int16_t port_src, u_int16_t port_dst,
			     TcpReassemblyData *data,
			     u_char */*ethHeader*/, u_int32_t /*ethHeaderLength*/,
			     u_int16_t /*handle_index*/, int /*dlt*/, int /*sensor_id*/, u_int32_t /*sensor_ip*/,
			     void */*uData*/, TcpReassemblyLink */*reassemblyLink*/,
			     std::ostream *debugStream) {
	++this->counterProcessData;
	if(debugStream) {
		(*debugStream) << "### WebrtcData::processData " << this->counterProcessData << endl;
	}
	if(!sqlDbSaveWebrtc) {
		sqlDbSaveWebrtc = createSqlObject();
	}
	for(size_t i_data = 0; i_data < data->data.size(); i_data++) {
		TcpReassemblyDataItem *dataItem = &data->data[i_data];
		if(!dataItem->getData()) {
			continue;
		}
		if(debugStream) {
			(*debugStream)
				<< fixed
				<< setw(15) << inet_ntostring(htonl(ip_src))
				<< " / "
				<< setw(5) << port_src
				<< (dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? " --> " : " <-- ")
				<< setw(15) << inet_ntostring(htonl(ip_dst))
				<< " / "
				<< setw(5) << port_dst
				<< "  len: " << setw(4) << dataItem->getDatalen();
			u_int32_t ack = dataItem->getAck();
			if(ack) {
				(*debugStream) << "  ack: " << setw(5) << ack;
			}
			(*debugStream) << endl;
		}
		WebrtcDecodeData webrtcDD;
		if(dataItem->getDatalen() > 4 &&
		   (!strncmp((char*)dataItem->getData(), "POST", 4) ||
		    !strncmp((char*)dataItem->getData(), "GET", 3) ||
		    !strncmp((char*)dataItem->getData(), "HTTP", 4))) {
			if(debugStream) {
				(*debugStream) << "  HTTP DATA: " << dataItem->getData() << endl;
			}
			continue;
		} else {
			unsigned int rsltDecode = webrtcDD.decode(dataItem->getData(), dataItem->getDatalen());
			if(rsltDecode) {
				if(webrtcDD.method == "hb") {
					if(debugStream) {
						(*debugStream) << "   method: hb - skip" << endl;
					}
					continue;
				}
				if(debugStream) {
					switch(webrtcDD.opcode) {
					case opcode_textData:
						(*debugStream) << "  WEBRTC " << webrtcDD.type << " DATA";
						if(webrtcDD.data) {
							(*debugStream)
								<< ": (len: " << strlen((char*)webrtcDD.data)
								<< " payload len: " << webrtcDD.payload_length << ") "
								<< webrtcDD.data;
						}
						(*debugStream) << endl;
						if(!webrtcDD.method.empty()) {
							(*debugStream) << "   method: " << webrtcDD.method << endl;
						}
						if(!webrtcDD.type.empty()) {
							(*debugStream) << "   type: " << webrtcDD.type << endl;
						}
						if(!webrtcDD.deviceId.empty()) {
							(*debugStream) << "   deviceId: " << webrtcDD.deviceId << endl;
						}
						if(!webrtcDD.commCorrelationId.empty()) {
							(*debugStream) << "   commCorrelationId: " << webrtcDD.commCorrelationId << endl;
						}
						break;
					case opcode_binaryData:
						(*debugStream) << "  WEBRTC BINARY DATA" << endl;
						break;
					case opcode_terminatesConnection:
						(*debugStream) << "  WEBRTC TERMINATES CONNECTION" << endl;
						break;
					default:
						(*debugStream) << "  WEBRTC OTHER OPCODE" << endl;
						break;
					}
				}
				if(rsltDecode != dataItem->getDatalen()) {
					if(debugStream) {
						(*debugStream) << "  WARNING - BAD LENGTH WEBRTC DATA" << endl;
					}
				}
				if(webrtcDD.opcode != opcode_textData) {
					continue;
				}
			} else {
				if(debugStream) {
					(*debugStream) << "  BAD WEBRTC DATA: " << endl;
				}
				continue;
			}
		}
		if((webrtcDD.opcode == opcode_textData && webrtcDD.data) &&
		   (webrtcDD.type == "req" || webrtcDD.type == "rsp") &&
		   ((webrtcDD.method == "login" && !webrtcDD.deviceId.empty()) || 
		    (webrtcDD.method == "msg" && !webrtcDD.commCorrelationId.empty()))) {
			uint32_t ip_ports[4] = { ip_src, ip_dst, port_src, port_dst };
			string data_md5 = GetDataMD5(webrtcDD.data, webrtcDD.payload_length,
						     (u_char*)ip_ports, sizeof(ip_ports));
			u_int32_t _ip_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_src : ip_dst;
			u_int32_t _ip_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_dst : ip_src;
			u_int16_t _port_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_src : port_dst;
			u_int16_t _port_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_dst : port_src;
			WebrtcDataCache requestDataFromCache = this->cache.get(_ip_src, _ip_dst, _port_src, _port_dst, data_md5);
			if(requestDataFromCache.timestamp) {
				if(debugStream) {
					(*debugStream) << "DUPL" << endl;
				}
			} else {
				SqlDb_row rowRequest;
				rowRequest.add(sqlDateTimeString(dataItem->getTime().tv_sec), "timestamp");
				rowRequest.add(dataItem->getTime().tv_usec, "usec");
				rowRequest.add(htonl(_ip_src), "srcip");
				rowRequest.add(htonl(_ip_dst), "dstip");
				rowRequest.add(_port_src, "srcport"); 
				rowRequest.add(_port_dst, "dstport"); 
				rowRequest.add(webrtcDD.type == "req" ? "websocket" : "websocket_resp", "type");
				rowRequest.add(webrtcDD.method, "method"); 
				rowRequest.add(sqlEscapeString((char*)webrtcDD.data).c_str(), "body");
				rowRequest.add(sqlEscapeString(!webrtcDD.deviceId.empty() ? 
								 webrtcDD.deviceId :
								 webrtcDD.commCorrelationId).c_str(), 
					       "external_transaction_id");
				rowRequest.add(opt_id_sensor > 0 ? opt_id_sensor : 0, "id_sensor", opt_id_sensor <= 0);
				string queryInsert = MYSQL_ADD_QUERY_END(sqlDbSaveWebrtc->insertQuery("webrtc", rowRequest));
				int storeId = STORE_PROC_ID_WEBRTC_1 + 
					      (opt_mysqlstore_max_threads_webrtc > 1 &&
					       sqlStore->getSize(STORE_PROC_ID_WEBRTC_1) > 1000 ? 
						counterProcessData % opt_mysqlstore_max_threads_webrtc : 
						0);
				sqlStore->query_lock(queryInsert.c_str(), storeId);
				if(debugStream) {
					(*debugStream) << "SAVE" << endl;
				}
				this->cache.add(_ip_src, _ip_dst, _port_src, _port_dst, data_md5,
						dataItem->getTime().tv_sec);
			}
		} else {
			if(debugStream) {
				(*debugStream) << "  UNCOMPLETE WEBRTC DATA: " << endl;
			}
		}
	}
	delete data;
	this->cache.cleanup(false);
}