%description: Test serializing frames %inifile: omnetpp.ini [General] #debugger-attach-on-startup=true #debugger-attach-on-error=true %includes: #include #include #include "inet/common/serializer/SerializerBase.h" #include "inet/common/serializer/headerserializers/EthernetCRC.h" #include "inet/common/serializer/headerserializers/ethernet/EthernetSerializer.h" #include "inet/common/serializer/headerserializers/ieee80211/Ieee80211Serializer.h" %global: using namespace inet; using namespace inet::serializer; #define PCAP_MAGIC 0xa1b2c3d4 /* "libpcap" file header (minus magic number). */ struct pcap_hdr { uint32_t magic; /* magic */ uint16_t version_major; /* major version number */ uint16_t version_minor; /* minor version number */ uint32_t thiszone; /* GMT to local correction */ uint32_t sigfigs; /* accuracy of timestamps */ uint32_t snaplen; /* max length of captured packets, in octets */ uint32_t network; /* data link type */ }; /* "libpcap" record header. */ struct pcaprec_hdr { int32_t ts_sec; /* timestamp seconds */ uint32_t ts_usec; /* timestamp microseconds */ uint32_t incl_len; /* number of octets of packet saved in file */ uint32_t orig_len; /* actual length of packet */ }; uint16_t swapByteOrder16(uint16_t v) { return ((v & 0xFF) << 8) | ((v & 0xFF00) >> 8); } uint32_t swapByteOrder32(uint32_t v) { return ((v & 0xFFL) << 24) | ((v & 0xFF00L) << 8) | ((v & 0xFF0000L) >> 8) | ((v & 0xFF000000L) >> 24); } #if OMNETPP_VERSION < 0x0500 //cClassDescriptor compatibility #define getFieldValueAsString(a, b, c) getFieldAsString((a), (b), (c)) #define getFieldProperty(a, b) getFieldProperty(nullptr, (a), (b)) #define getFieldName(a) getFieldName(nullptr, (a)) #define getFieldIsCObject(a) getFieldIsCObject(nullptr, (a)) #define getFieldCount() getFieldCount(nullptr) #define getFieldTypeString(a) getFieldTypeString(nullptr, (a)) #define getFieldIsArray(a) getFieldIsArray(nullptr, (a)) #define getFieldArraySize(a, b) getArraySize((a), (b)) #define getFieldStructValuePointer(a, b, c) getFieldStructPointer((a), (b), (c)) #define getFieldTypeFlags(a) getFieldTypeFlags(nullptr, (a)) #define getFieldStructName(a) getFieldStructName(nullptr, (a)) #endif // OMNETPP_VERSION < 0x0500 static void printobject(cObject* object) { EV << object->getClassName() << ":" << endl; cClassDescriptor *descriptor = object->getDescriptor(); for (int i = 0; i < descriptor->getFieldCount(); i++) { EV << " " << descriptor->getFieldName(i) << ": "; if (descriptor->getFieldIsArray(i)) { for (int j = 0; j < descriptor->getFieldArraySize(object, i); j++) { EV << " [" << j << "]: " << descriptor->getFieldValueAsString(object,i,j) << endl; } } else EV << descriptor->getFieldValueAsString(object,i,0) << endl; } } static void testRecord(const char* filename, bool fcs = true) { FILE *pcapFile; struct pcap_hdr fileHeader; struct pcaprec_hdr recordHeader; static uint8_t readBuf[60000]; static uint8_t writeBuf[60000]; memset((void*)&readBuf, 0, sizeof(readBuf)); memset((void*)&writeBuf, 0, sizeof(writeBuf)); EV << "=== Testing file " << filename << endl; pcapFile = fopen(filename, "rb"); if (!pcapFile) throw cRuntimeError("pcap file '%s' can not opened.", filename); size_t err = fread(&fileHeader, sizeof(fileHeader), 1, pcapFile); if (err != 1) throw cRuntimeError("Can not read pcap fileheader from file '%s', errno is %ld.", filename, err); if (fileHeader.magic == 0xa1b2c3d4) { } else if (fileHeader.magic == 0xd4c3b2a1) { fileHeader.version_major = swapByteOrder16(fileHeader.version_major); fileHeader.version_minor = swapByteOrder16(fileHeader.version_minor); fileHeader.thiszone = swapByteOrder32(fileHeader.thiszone); fileHeader.sigfigs = swapByteOrder32(fileHeader.sigfigs); fileHeader.snaplen = swapByteOrder32(fileHeader.snaplen); fileHeader.network = swapByteOrder32(fileHeader.network); } else throw cRuntimeError("unknown pcap fileheader from file '%s'", filename); err = fread(&recordHeader, sizeof(recordHeader), 1, pcapFile); if (err != 1) throw cRuntimeError("Can not read pcap recordheader from file '%s', errno is %ld.", filename, err); if (fileHeader.magic != 0xa1b2c3d4) { recordHeader.ts_sec = swapByteOrder32(recordHeader.ts_sec); recordHeader.ts_usec = swapByteOrder32(recordHeader.ts_usec); recordHeader.orig_len = swapByteOrder32(recordHeader.orig_len); recordHeader.incl_len = swapByteOrder32(recordHeader.incl_len); } fread(&readBuf, recordHeader.incl_len, 1, pcapFile); fclose(pcapFile); uint32_t serializedLength = 0; uint32_t incl_len = recordHeader.incl_len; if (! fcs && fileHeader.network == LINKTYPE_ETHERNET && recordHeader.incl_len == recordHeader.orig_len) { // add FCS Buffer b(readBuf, incl_len + 4); b.seek(incl_len); uint32_t fcs = ethernetCRC(b._getBuf(), b.getPos()); b.writeUint32(fcs); incl_len = b.getPos(); } Buffer rb(readBuf, incl_len); Buffer wb(writeBuf, sizeof(writeBuf)); Context c; cPacket *frame = SerializerBase::lookupAndDeserialize(rb, c, LINKTYPE, fileHeader.network); ASSERT(frame); for (cPacket *temp = frame; temp; temp = temp->getEncapsulatedPacket()) printobject(temp); SerializerBase::lookupAndSerialize(frame, wb, c, LINKTYPE, fileHeader.network); serializedLength = wb.getPos(); delete frame; if(incl_len == serializedLength) EV << "Frame lengths are the same" << endl; else EV << "Frame lengths are not the same: " << incl_len << " ws " << serializedLength << endl; if(incl_len == serializedLength && !memcmp(readBuf, writeBuf, fcs ? serializedLength : serializedLength - 4)) EV << "Frames are the same" << endl; else EV << "Frames are not the same" << endl; } %activity: testRecord("../../pcap/rarp_request.pcap", false); testRecord("../../pcap/rarp_req_reply.pcap", false); testRecord("../../pcap/Ethernet_Pause_Frame.pcap", false); testRecord("../../pcap/eth_fcs_good.pcap", true); //testRecord("../../pcap/v6.pcap", false); //testRecord("../../pcap/tcp_ok_capture.pcap", false); //testRecord("../../pcap/80211ack.pcap", false); %contains-regex: stdout === Testing file ../../pcap/rarp_request.pcap .* Frames are the same === Testing file ../../pcap/rarp_req_reply.pcap .* Frames are the same === Testing file ../../pcap/Ethernet_Pause_Frame.pcap .* Frames are the same === Testing file ../../pcap/eth_fcs_good.pcap .* Frames are the same %not-contains: stdout Frames are not the same