Skip to content

Commit 855cb63

Browse files
committed
Basic support for <checksum> suffix layer in commsdsl2wireshark.
1 parent 80ad34e commit 855cb63

18 files changed

Lines changed: 672 additions & 22 deletions

app/commsdsl2comms/src/CommsChecksumLayer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ bool CommsChecksumLayer::genPrepareImpl()
4747
CommsChecksumLayer::CommsIncludesList CommsChecksumLayer::commsDefIncludesImpl() const
4848
{
4949
CommsIncludesList result;
50-
auto obj = genChecksumDslObj();
50+
auto obj = genChecksumParseObj();
5151
if (!obj.parseFromLayer().empty()) {
5252
assert(obj.parseUntilLayer().empty());
5353
result.push_back("comms/frame/ChecksumLayer.h");
@@ -108,7 +108,7 @@ std::string CommsChecksumLayer::commsDefBaseTypeImpl(const std::string& prevName
108108
repl["COMMA"] = std::string(",");
109109
}
110110

111-
if (!genChecksumDslObj().parseUntilLayer().empty()) {
111+
if (!genChecksumParseObj().parseUntilLayer().empty()) {
112112
repl["PREFIX_VAR"] = "Prefix";
113113
}
114114

@@ -130,7 +130,7 @@ std::string CommsChecksumLayer::commsDefAlgInternal() const
130130
static_assert(ClassMapSize == static_cast<std::size_t>(commsdsl::parse::ParseChecksumLayer::ParseAlg::NumOfValues),
131131
"Invalid map");
132132

133-
auto obj = genChecksumDslObj();
133+
auto obj = genChecksumParseObj();
134134
auto alg = obj.parseAlg();
135135
auto idx = static_cast<std::size_t>(alg);
136136

@@ -171,7 +171,7 @@ std::string CommsChecksumLayer::commsDefAlgInternal() const
171171
std::string CommsChecksumLayer::commsDefExtraOptInternal() const
172172
{
173173
std::string result;
174-
if (genChecksumDslObj().parseVerifyBeforeRead()) {
174+
if (genChecksumParseObj().parseVerifyBeforeRead()) {
175175
result = "comms::option::def::FrameLayerVerifyBeforeRead";
176176
}
177177
return result;

app/commsdsl2wireshark/src/Wireshark.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ std::string Wireshark::wiresharkPacketIdFuncName(const WiresharkGenerator& gener
117117
return wiresharkLocalNamespaceName(generator) + ".packet_id";
118118
}
119119

120+
std::string Wireshark::wiresharkCreateCrcFuncName(const WiresharkGenerator& generator)
121+
{
122+
return wiresharkLocalNamespaceName(generator) + ".create_crc_calc";
123+
}
124+
120125
bool Wireshark::wiresharkWriteInternal() const
121126
{
122127
auto fileName = wiresharkFileName(m_wiresharkGenerator);
@@ -138,6 +143,7 @@ bool Wireshark::wiresharkWriteInternal() const
138143
"#^#PROT_VERSION#$#\n"
139144
"#^#STATUS_CODE#$#\n"
140145
"#^#OPT_MODE#$#\n"
146+
"#^#CRC#$#\n"
141147
"#^#FIELDS_REG#$#\n"
142148
"#^#EXTRACTORS_DECL#$#\n"
143149
"#^#FIELD_VALUE_FUNC#$#\n"
@@ -165,6 +171,7 @@ bool Wireshark::wiresharkWriteInternal() const
165171
{"FIELD_VALUE_FUNC", wiresharkFieldValueFuncInternal()},
166172
{"PROT_VERSION", wiresharkProtocolVersionDefInternal()},
167173
{"PINFO", wiresharkPinfoDefInternal()},
174+
{"CRC", wiresharkCrcCodeDefInternal()},
168175
};
169176

170177
auto str = commsdsl::gen::util::genProcessTemplate(Templ, repl, true);
@@ -517,6 +524,110 @@ std::string Wireshark::wiresharkPinfoDefInternal() const
517524
return util::genProcessTemplate(Templ, repl);
518525
}
519526

527+
std::string Wireshark::wiresharkCrcCodeDefInternal() const
528+
{
529+
auto& schemas = m_wiresharkGenerator.genSchemas();
530+
bool hasCrc =
531+
std::any_of(
532+
schemas.begin(), schemas.end(),
533+
[](auto& sPtr)
534+
{
535+
return WiresharkSchema::wiresharkCast(*sPtr).wiresharkNeedsCrcCalc();
536+
});
537+
538+
if (!hasCrc) {
539+
return strings::genEmptyString();
540+
}
541+
542+
const std::string Templ =
543+
"function #^#NAME#$#(width, poly, init, ref_in, ref_out, xor_out)\n"
544+
" local function reflect(val, w)\n"
545+
" local res = 0\n"
546+
" for i = 0, w - 1 do\n"
547+
" if bit32.band(bit32.rshift(val, i), 1) == 1 then\n"
548+
" res = bit32.bor(res, bit32.lshift(1, w - 1 - i))\n"
549+
" end\n"
550+
" end\n"
551+
" return res\n"
552+
" end\n"
553+
"\n"
554+
" local tbl = {}\n"
555+
" local mask = (width == 32) and 0xFFFFFFFF or (bit32.lshift(1, width) - 1)\n"
556+
" local msb_mask = bit32.lshift(1, width - 1)\n"
557+
"\n"
558+
" -- Precompute the 256-value lookup table for this specific CRC profile\n"
559+
" for i = 0, 255 do\n"
560+
" local crc\n"
561+
" if ref_in then\n"
562+
" crc = i\n"
563+
" local ref_poly = reflect(poly, width)\n"
564+
" for j = 1, 8 do\n"
565+
" if bit32.band(crc, 1) == 1 then\n"
566+
" crc = bit32.bxor(bit32.rshift(crc, 1), ref_poly)\n"
567+
" else\n"
568+
" crc = bit32.rshift(crc, 1)\n"
569+
" end\n"
570+
" end\n"
571+
" else\n"
572+
" crc = bit32.lshift(i, width - 8)\n"
573+
" for j = 1, 8 do\n"
574+
" if bit32.band(crc, msb_mask) ~= 0 then\n"
575+
" crc = bit32.bxor(bit32.lshift(crc, 1), poly)\n"
576+
" else\n"
577+
" crc = bit32.lshift(crc, 1)\n"
578+
" end\n"
579+
" end\n"
580+
" end\n"
581+
" tbl[i] = bit32.band(crc, mask)\n"
582+
" end\n"
583+
"\n"
584+
" -- Return the actual high-speed checksum function\n"
585+
" -- Accepts tvb, offset, and offset_limit (exclusive end index)\n"
586+
" return function(tvb, offset, offset_limit)\n"
587+
" local crc = init\n"
588+
" local length = offset_limit - offset\n"
589+
" if length <= 0 then\n"
590+
" return init\n"
591+
" end\n"
592+
"\n"
593+
" -- Extracting raw bytes once is massively faster than calling tvb:range(i, 1) in a loop\n"
594+
" local data = tvb:range(offset, length):raw()\n"
595+
"\n"
596+
" for i = 1, #data do\n"
597+
" local byte = data:byte(i)\n"
598+
" if ref_in then\n"
599+
" local idx = bit32.band(bit32.bxor(crc, byte), 0xFF)\n"
600+
" crc = bit32.bxor(bit32.rshift(crc, 8), tbl[idx])\n"
601+
" else\n"
602+
" local idx = bit32.band(bit32.bxor(bit32.rshift(crc, width - 8), byte), 0xFF)\n"
603+
" crc = bit32.bxor(bit32.lshift(crc, 8), tbl[idx])\n"
604+
" end\n"
605+
" crc = bit32.band(crc, mask)\n"
606+
" end\n"
607+
"\n"
608+
" -- If output reflection differs from input reflection, we must reflect it\n"
609+
" if ref_out ~= ref_in then\n"
610+
" crc = reflect(crc, width)\n"
611+
" end\n"
612+
"\n"
613+
" crc = bit32.bxor(crc, xor_out)\n"
614+
"\n"
615+
" -- Force unsigned 32-bit (for environments where bitwise ops return signed 32-bit)\n"
616+
" if crc < 0 then\n"
617+
" crc = crc + 4294967296\n"
618+
" end\n"
619+
"\n"
620+
" return bit32.band(crc, mask)\n"
621+
" end\n"
622+
"end\n";
623+
624+
util::GenReplacementMap repl = {
625+
{"NAME", wiresharkCreateCrcFuncName(m_wiresharkGenerator)},
626+
};
627+
628+
return util::genProcessTemplate(Templ, repl);
629+
}
630+
520631
const std::string& Wireshark::wiresharkStatusCodeStrInternal(WiresharkStatusCode code)
521632
{
522633
static const std::string Map[] = {
@@ -525,7 +636,9 @@ const std::string& Wireshark::wiresharkStatusCodeStrInternal(WiresharkStatusCode
525636
/* MalformedData */ "MALFORMED_PACKET",
526637
/* InvalidMsgId */ "INVALID_MSG_ID",
527638
/* InvalidMsgData */ "INVALID_MSG_DATA",
639+
/* ChecksumError */ "CHECKSUM_ERROR",
528640
/* CodegenError */ "CODEGEN_ERROR",
641+
/* InvalidFrame */ "INVALID_FRAME",
529642
};
530643
static const std::size_t MapSize = std::extent_v<decltype(Map)>;
531644
static_assert(MapSize == static_cast<unsigned>(WiresharkStatusCode::ValuesLimit));

app/commsdsl2wireshark/src/Wireshark.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ class Wireshark
3030
MalformedPacket,
3131
InvalidMsgId,
3232
InvalidMsgData,
33+
ChecksumError,
3334
CodegenError,
35+
InvalidFrame,
3436
ValuesLimit // Must be last
3537
};
3638

@@ -57,6 +59,7 @@ class Wireshark
5759
static std::string wiresharkProtVersionSetFuncName(const WiresharkGenerator& generator);
5860
static std::string wiresharkPinfoName(const WiresharkGenerator& generator);
5961
static std::string wiresharkPacketIdFuncName(const WiresharkGenerator& generator);
62+
static std::string wiresharkCreateCrcFuncName(const WiresharkGenerator& generator);
6063

6164
private:
6265
explicit Wireshark(const WiresharkGenerator& generator) : m_wiresharkGenerator(generator) {}
@@ -78,6 +81,8 @@ class Wireshark
7881
std::string wiresharkFieldValueFuncInternal() const;
7982
std::string wiresharkProtocolVersionDefInternal() const;
8083
std::string wiresharkPinfoDefInternal() const;
84+
std::string wiresharkCrcCodeDefInternal() const;
85+
8186
static const std::string& wiresharkStatusCodeStrInternal(WiresharkStatusCode code);
8287
static const std::string& wiresharkOptModeStrInternal(WiresharkOptMode code);
8388

0 commit comments

Comments
 (0)