123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- #ifndef UA_DEBUG_DUMP_PKGS_FILE
- #error UA_DEBUG_DUMP_PKGS_FILE must be defined
- #endif
- #include <open62541/transport_generated_encoding_binary.h>
- #include <open62541/types.h>
- #include <open62541/types_generated_encoding_binary.h>
- #include "server/ua_server_internal.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #define UA_DUMP_RAM_SIZE 8 * 1024 * 1024
- unsigned int UA_dump_chunkCount = 0;
- char *UA_dump_messageTypes[] = {"ack", "hel", "msg", "opn", "clo", "err", "unk"};
- struct UA_dump_filename {
- const char *messageType;
- char serviceName[100];
- };
- void UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection,
- UA_ByteString *messageBuffer);
- static const char *
- UA_debug_dumpGetMessageTypePrefix(UA_UInt32 messageType) {
- switch(messageType & 0x00ffffff) {
- case UA_MESSAGETYPE_ACK:
- return UA_dump_messageTypes[0];
- case UA_MESSAGETYPE_HEL:
- return UA_dump_messageTypes[1];
- case UA_MESSAGETYPE_MSG:
- return UA_dump_messageTypes[2];
- case UA_MESSAGETYPE_OPN:
- return UA_dump_messageTypes[3];
- case UA_MESSAGETYPE_CLO:
- return UA_dump_messageTypes[4];
- case UA_MESSAGETYPE_ERR:
- return UA_dump_messageTypes[5];
- default:
- return UA_dump_messageTypes[6];
- }
- }
- static UA_StatusCode
- UA_debug_dumpSetServiceName(const UA_ByteString *msg, char serviceNameTarget[100]) {
-
- size_t offset = 0;
-
- UA_NodeId requestTypeId;
- UA_StatusCode retval = UA_NodeId_decodeBinary(msg, &offset, &requestTypeId);
- if(retval != UA_STATUSCODE_GOOD)
- return retval;
- if(requestTypeId.identifierType != UA_NODEIDTYPE_NUMERIC || requestTypeId.namespaceIndex != 0) {
- snprintf(serviceNameTarget, 100, "invalid_request_id");
- return UA_STATUSCODE_BADUNEXPECTEDERROR;
- }
- const UA_DataType *requestType = NULL;
- for (size_t i=0; i<UA_TYPES_COUNT; i++) {
- if (UA_TYPES[i].binaryEncodingId == requestTypeId.identifier.numeric) {
- requestType = &UA_TYPES[i];
- break;
- }
- }
- if (requestType == NULL) {
- snprintf(serviceNameTarget, 100, "invalid_request_no_type");
- return UA_STATUSCODE_BADUNEXPECTEDERROR;
- }
- snprintf(serviceNameTarget, 100, "_%s", requestType->typeName);
- return UA_STATUSCODE_GOOD;
- }
- static UA_StatusCode
- UA_debug_dump_setName_withoutChannel(UA_Server *server, UA_Connection *connection,
- UA_ByteString *message, struct UA_dump_filename* dump_filename) {
- size_t offset = 0;
- UA_TcpMessageHeader tcpMessageHeader;
- UA_StatusCode retval =
- UA_TcpMessageHeader_decodeBinary(message, &offset, &tcpMessageHeader);
- if(retval != UA_STATUSCODE_GOOD)
- return retval;
- dump_filename->messageType =
- UA_debug_dumpGetMessageTypePrefix(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff);
- if ((tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff) == UA_MESSAGETYPE_MSG) {
-
- UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Got MSG package without channel.");
- return UA_STATUSCODE_BADUNEXPECTEDERROR;
- }
- return UA_STATUSCODE_GOOD;
- }
- static void
- UA_debug_dump_setName_withChannel(void *application, UA_SecureChannel *channel,
- UA_MessageType messagetype, UA_UInt32 requestId,
- const UA_ByteString *message) {
- struct UA_dump_filename *dump_filename = (struct UA_dump_filename *)application;
- dump_filename->messageType = UA_debug_dumpGetMessageTypePrefix(messagetype);
- if(messagetype == UA_MESSAGETYPE_MSG)
- UA_debug_dumpSetServiceName(message, dump_filename->serviceName);
- }
- void
- UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection,
- UA_ByteString *messageBuffer) {
- struct UA_dump_filename dump_filename;
- dump_filename.messageType = NULL;
- dump_filename.serviceName[0] = 0;
- if(!connection->channel) {
- UA_debug_dump_setName_withoutChannel(server, connection, messageBuffer, &dump_filename);
- } else {
- UA_SecureChannel dummy = *connection->channel;
- TAILQ_INIT(&dummy.messages);
- UA_ByteString messageBufferCopy;
- UA_ByteString_copy(messageBuffer, &messageBufferCopy);
- UA_SecureChannel_decryptAddChunk(&dummy, &messageBufferCopy, UA_TRUE);
- UA_SecureChannel_processCompleteMessages(&dummy, &dump_filename, UA_debug_dump_setName_withChannel);
- UA_SecureChannel_deleteMessages(&dummy);
- UA_ByteString_deleteMembers(&messageBufferCopy);
- }
- char fileName[250];
- snprintf(fileName, sizeof(fileName), "%s/%05u_%s%s", UA_CORPUS_OUTPUT_DIR, ++UA_dump_chunkCount,
- dump_filename.messageType ? dump_filename.messageType : "", dump_filename.serviceName);
- char dumpOutputFile[266];
- snprintf(dumpOutputFile, 255, "%s.bin", fileName);
-
- unsigned cnt = 1;
- while ( access( dumpOutputFile, F_OK ) != -1 ) {
- snprintf(dumpOutputFile, 266, "%s_%u.bin", fileName, cnt);
- cnt++;
- }
- UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
- "Dumping package %s", dumpOutputFile);
- FILE *write_ptr = fopen(dumpOutputFile, "ab");
- fwrite(messageBuffer->data, messageBuffer->length, 1, write_ptr);
-
- uint32_t ramSize = UA_DUMP_RAM_SIZE;
- fwrite(&ramSize, sizeof(ramSize), 1, write_ptr);
- fclose(write_ptr);
- }
|