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); }
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; }
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); }