Skip to content

Commit 984a6c5

Browse files
committed
Supporting <list> code generation in commsdsl2wireshark.
1 parent bd00059 commit 984a6c5

4 files changed

Lines changed: 223 additions & 25 deletions

File tree

app/commsdsl2comms/src/CommsListField.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ bool CommsListField::genPrepareImpl()
5050
return nullptr;
5151
}
5252

53-
auto* commsField = CommsField::commsCast(field);
53+
auto* commsField = dynamic_cast<CommsField*>(field);
5454
assert(commsField != nullptr);
5555
return commsField;
5656
};

app/commsdsl2wireshark/src/WiresharkListField.cpp

Lines changed: 188 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ std::string WiresharkListField::wiresharkDissectBodyImpl([[maybe_unused]] const
178178

179179
static const std::string Templ =
180180
"local count = 0\n"
181-
"local #^#SUBTREE#$# = #^#TREE#$#:add(#^#FIELD#$#, #^#TVB#$#(#^#NEXT_OFFSET#$#, 0))\n"
181+
"local #^#SUBTREE#$# = #^#TREE#$#:add(#^#FIELD#$#, #^#TVB#$#(#^#NEXT_OFFSET#$#, -1))\n"
182182
"#^#READ#$#\n"
183183
"#^#NAME#$#_size_rec_set(#^#FIELD#$#, count)\n"
184184
"#^#SUBTREE#$#:set_len(#^#NEXT_OFFSET#$# - #^#OFFSET#$#)\n"
@@ -201,11 +201,24 @@ std::string WiresharkListField::wiresharkDissectBodyImpl([[maybe_unused]] const
201201
break;
202202
}
203203

204-
if (parseObj.parseHasCountPrefixField()) {
204+
if ((parseObj.parseHasCountPrefixField()) ||
205+
(!parseObj.parseDetachedCountPrefixFieldName().empty())) {
205206
repl["READ"] = wiresharkCountPrefixDissectInternal();
206207
break;
207208
}
208209

210+
if ((parseObj.parseHasLengthPrefixField()) ||
211+
(!parseObj.parseDetachedLengthPrefixFieldName().empty())) {
212+
repl["READ"] = wiresharkLengthPrefixDissectInternal();
213+
break;
214+
}
215+
216+
if ((parseObj.parseHasTermSuffixField()) ||
217+
(!parseObj.parseDetachedTermSuffixFieldName().empty())) {
218+
repl["READ"] = wiresharkTermSuffixDissectInternal();
219+
break;
220+
}
221+
209222
repl["READ"] = "-- TODO: implement";
210223
} while (false);
211224

@@ -339,11 +352,26 @@ std::string WiresharkListField::wiresharkFixedCountDissectInternal() const
339352

340353
std::string WiresharkListField::wiresharkCountPrefixDissectInternal() const
341354
{
342-
auto* prefixField = m_wiresharkFields[WiresharkFieldIdx_ExternalCountPrefix];
355+
const auto* prefixField = m_wiresharkFields[WiresharkFieldIdx_ExternalCountPrefix];
343356
if (prefixField == nullptr) {
344357
prefixField = m_wiresharkFields[WiresharkFieldIdx_MemberCountPrefix];
345358
}
346359

360+
if (prefixField == nullptr) {
361+
// TODO: test
362+
auto parseObj = genListFieldParseObj();
363+
auto& detachedName = parseObj.parseDetachedCountPrefixFieldName();
364+
assert(!detachedName.empty());
365+
auto sibInfo = wiresharkSplitMemberAccStr(detachedName, wiresharkSiblings());
366+
prefixField = sibInfo.first;
367+
if (!sibInfo.second.empty()) {
368+
assert(sibInfo.first != nullptr);
369+
auto memInfo = sibInfo.first->wiresharkGenField().genProcessInnerRef(sibInfo.second);
370+
prefixField = WiresharkField::wiresharkCast(memInfo.m_field);
371+
assert(memInfo.m_refType == GenField::FieldRefType_Field);
372+
}
373+
}
374+
347375
assert(prefixField != nullptr);
348376

349377
static const std::string Templ =
@@ -369,13 +397,125 @@ std::string WiresharkListField::wiresharkCountPrefixDissectInternal() const
369397
{"FIELD", prefixField->wiresharkFieldObjName()},
370398
{"SUCCESS", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::Success)},
371399
{"OFFSET", wiresharkOffsetStr()},
372-
{"VALUE_FUNC", wiresharkValueFuncName()},
400+
{"VALUE_FUNC", prefixField->wiresharkValueFuncName()},
373401
{"READ_ELEM", wiresharkDissectElemCodeInternal()},
374402
};
375403

376404
return util::genProcessTemplate(Templ, repl);
377405
}
378406

407+
std::string WiresharkListField::wiresharkLengthPrefixDissectInternal() const
408+
{
409+
const auto* prefixField = m_wiresharkFields[WiresharkFieldIdx_ExternalLengthPrefix];
410+
if (prefixField == nullptr) {
411+
prefixField = m_wiresharkFields[WiresharkFieldIdx_MemberLenthPrefix];
412+
}
413+
414+
if (prefixField == nullptr) {
415+
// TODO: test
416+
auto parseObj = genListFieldParseObj();
417+
auto& detachedName = parseObj.parseDetachedLengthPrefixFieldName();
418+
assert(!detachedName.empty());
419+
auto sibInfo = wiresharkSplitMemberAccStr(detachedName, wiresharkSiblings());
420+
prefixField = sibInfo.first;
421+
if (!sibInfo.second.empty()) {
422+
assert(sibInfo.first != nullptr);
423+
auto memInfo = sibInfo.first->wiresharkGenField().genProcessInnerRef(sibInfo.second);
424+
prefixField = WiresharkField::wiresharkCast(memInfo.m_field);
425+
assert(memInfo.m_refType == GenField::FieldRefType_Field);
426+
}
427+
}
428+
429+
assert(prefixField != nullptr);
430+
431+
static const std::string Templ =
432+
"#^#RESULT#$#, #^#NEXT_OFFSET#$# = #^#DISSECT#$#(#^#TVB#$#, #^#SUBTREE#$#, #^#NEXT_OFFSET#$#, #^#LIMIT#$#, #^#FIELD#$#)\n"
433+
"if #^#RESULT#$# ~= #^#SUCCESS#$# then\n"
434+
" return #^#RESULT#$#, #^#OFFSET#$#\n"
435+
"end\n"
436+
"\n"
437+
"local next_limit = #^#NEXT_OFFSET#$# + #^#VALUE_FUNC#$#(#^#FIELD#$#)\n"
438+
"if #^#LIMIT#$# < next_limit then\n"
439+
" return #^#NOT_ENOUGH_DATA#$#, #^#OFFSET#$#\n"
440+
"end\n"
441+
"\n"
442+
"#^#LIMIT#$# = next_limit\n"
443+
"while (#^#NEXT_OFFSET#$# < #^#LIMIT#$#) do\n"
444+
" #^#READ_ELEM#$#\n"
445+
"end\n"
446+
;
447+
448+
auto& wiresharkGenerator = WiresharkGenerator::wiresharkCast(genGenerator());
449+
util::GenReplacementMap repl = {
450+
{"RESULT", wiresharkResultStr()},
451+
{"NEXT_OFFSET", wiresharkNextOffsetStr()},
452+
{"DISSECT", prefixField->wiresharkDissectName()},
453+
{"TVB", wiresharkTvbStr()},
454+
{"SUBTREE", wiresharkFieldSubtreeStr()},
455+
{"LIMIT", wiresharkOffsetLimitStr()},
456+
{"FIELD", prefixField->wiresharkFieldObjName()},
457+
{"SUCCESS", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::Success)},
458+
{"NOT_ENOUGH_DATA", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::NotEnoughData)},
459+
{"OFFSET", wiresharkOffsetStr()},
460+
{"VALUE_FUNC", prefixField->wiresharkValueFuncName()},
461+
{"READ_ELEM", wiresharkDissectElemCodeInternal()},
462+
};
463+
464+
return util::genProcessTemplate(Templ, repl);
465+
}
466+
467+
std::string WiresharkListField::wiresharkTermSuffixDissectInternal() const
468+
{
469+
const auto* suffixField = m_wiresharkFields[WiresharkFieldIdx_ExternalTermSuffix];
470+
if (suffixField == nullptr) {
471+
suffixField = m_wiresharkFields[WiresharkFieldIdx_MemberTermSuffix];
472+
}
473+
474+
if (suffixField == nullptr) {
475+
auto parseObj = genListFieldParseObj();
476+
auto& detachedName = parseObj.parseDetachedTermSuffixFieldName();
477+
assert(!detachedName.empty());
478+
auto sibInfo = wiresharkSplitMemberAccStr(detachedName, wiresharkSiblings());
479+
suffixField = sibInfo.first;
480+
if (!sibInfo.second.empty()) {
481+
assert(sibInfo.first != nullptr);
482+
auto memInfo = sibInfo.first->wiresharkGenField().genProcessInnerRef(sibInfo.second);
483+
suffixField = WiresharkField::wiresharkCast(memInfo.m_field);
484+
assert(memInfo.m_refType == GenField::FieldRefType_Field);
485+
}
486+
}
487+
488+
assert(suffixField != nullptr);
489+
490+
static const std::string Templ =
491+
"while (#^#NEXT_OFFSET#$# < #^#LIMIT#$#) do\n"
492+
" local term_suffix_subtree = #^#SUBTREE#$#:add(#^#PROTO#$#, #^#TVB#$#(#^#NEXT_OFFSET#$#, 0))\n"
493+
" term_suffix_subtree:set_hidden(true)\n"
494+
" #^#RESULT#$#, #^#NEXT_OFFSET#$# = #^#DISSECT#$#(#^#TVB#$#, term_suffix_subtree, #^#NEXT_OFFSET#$#, #^#LIMIT#$#, #^#FIELD#$#)\n"
495+
" if #^#RESULT#$# == #^#SUCCESS#$# then\n"
496+
" break\n"
497+
" end\n"
498+
" #^#READ_ELEM#$#\n"
499+
"end\n"
500+
;
501+
502+
auto& wiresharkGenerator = WiresharkGenerator::wiresharkCast(genGenerator());
503+
util::GenReplacementMap repl = {
504+
{"RESULT", wiresharkResultStr()},
505+
{"NEXT_OFFSET", wiresharkNextOffsetStr()},
506+
{"DISSECT", suffixField->wiresharkDissectName()},
507+
{"TVB", wiresharkTvbStr()},
508+
{"SUBTREE", wiresharkFieldSubtreeStr()},
509+
{"LIMIT", wiresharkOffsetLimitStr()},
510+
{"FIELD", suffixField->wiresharkFieldObjName()},
511+
{"SUCCESS", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::Success)},
512+
{"READ_ELEM", wiresharkDissectElemCodeInternal()},
513+
{"PROTO", Wireshark::wiresharkProtocolObjName(wiresharkGenerator)},
514+
};
515+
516+
return util::genProcessTemplate(Templ, repl);
517+
}
518+
379519
std::string WiresharkListField::wiresharkElemLimitCodeInternal() const
380520
{
381521
auto parseObj = genListFieldParseObj();
@@ -390,14 +530,16 @@ std::string WiresharkListField::wiresharkElemLimitCodeInternal() const
390530

391531
assert(lenField != nullptr);
392532

533+
auto& wiresharkGenerator = WiresharkGenerator::wiresharkCast(genGenerator());
534+
393535
static const std::string ReadTempl =
394-
"#^#RESULT#$#, #^#NEXT_OFFSET#$# = #^#DISSECT#$#(#^#TVB#$#, #^#SUBTREE#$#, #^#NEXT_OFFSET#$#, #^#LIMIT#$#, #^#FIELD#$#)"
536+
"#^#RESULT#$#, #^#NEXT_OFFSET#$# = #^#DISSECT#$#(#^#TVB#$#, #^#SUBTREE#$#, #^#NEXT_OFFSET#$#, #^#LIMIT#$#, #^#FIELD#$#)\n"
537+
"#^#LEN_CHECK#$#\n"
395538
"if #^#RESULT#$# ~= #^#SUCCESS#$# then\n"
396539
" return #^#RESULT#$#, #^#OFFSET#$#\n"
397540
"end\n"
398541
;
399542

400-
auto& wiresharkGenerator = WiresharkGenerator::wiresharkCast(genGenerator());
401543
util::GenReplacementMap readRepl = {
402544
{"RESULT", wiresharkResultStr()},
403545
{"NEXT_OFFSET", wiresharkNextOffsetStr()},
@@ -410,38 +552,60 @@ std::string WiresharkListField::wiresharkElemLimitCodeInternal() const
410552
{"OFFSET", wiresharkOffsetStr()},
411553
};
412554

555+
if (genListFieldParseObj().parseHasLengthPrefixField()) {
556+
static const std::string LenCheckTempl =
557+
"if #^#RESULT#$# == #^#NOT_ENOUGH_DATA#$# then\n"
558+
" return #^#MALFORMED#$#, #^#OFFSET#$#\n"
559+
"end\n"
560+
;
561+
562+
util::GenReplacementMap lenCheckRepl = {
563+
{"RESULT", wiresharkResultStr()},
564+
{"NOT_ENOUGH_DATA", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::NotEnoughData)},
565+
{"MALFORMED", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::MalformedPacket)},
566+
{"OFFSET", wiresharkOffsetStr()},
567+
};
568+
569+
readRepl["LEN_CHECK"] = util::genProcessTemplate(LenCheckTempl, lenCheckRepl);
570+
}
571+
413572
static const std::string ValueTempl =
414-
"local elem_limit = #^#VALUE_FUNC#$#(#^#FIELD#$#)"
573+
"local elem_limit = #^#NEXT_OFFSET#$# + #^#VALUE_FUNC#$#(#^#FIELD#$#)\n"
574+
"if (#^#LIMIT#$# < elem_limit) then\n"
575+
" return #^#RESULT_VAL#$#, #^#OFFSET#$#\n"
576+
"end\n"
415577
;
416578

417579
util::GenReplacementMap valueRepl = {
418580
{"VALUE_FUNC", lenField->wiresharkValueFuncName()},
419581
{"FIELD", lenField->wiresharkFieldObjName()},
582+
{"RESULT_VAL", Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::NotEnoughData)},
583+
{"OFFSET", wiresharkOffsetStr()},
584+
{"LIMIT", wiresharkOffsetLimitStr()},
585+
{"NEXT_OFFSET", wiresharkNextOffsetStr()},
420586
};
421587

588+
if (genListFieldParseObj().parseHasLengthPrefixField()) {
589+
valueRepl["RESULT_VAL"] = Wireshark::wiresharkStatusCodeStr(wiresharkGenerator, Wireshark::WiresharkStatusCode::MalformedPacket);
590+
}
591+
422592
if (!parseObj.parseElemFixedLength()) {
423593
return util::genProcessTemplate(ReadTempl, readRepl) + '\n' + util::genProcessTemplate(ValueTempl, valueRepl);
424594
}
425595

426-
if ((parseObj.parseFixedCount()) ||
427-
(parseObj.parseHasCountPrefixField())) {
428-
static const std::string FixedCountTempl =
429-
"if cnt == 1 then\n"
430-
" #^#READ#$#\n"
431-
"end\n"
432-
"#^#VALUE#$#\n"
433-
;
434-
435-
util::GenReplacementMap fixedCountRepl = {
436-
{"READ", util::genProcessTemplate(ReadTempl, readRepl)},
437-
{"VALUE", util::genProcessTemplate(ValueTempl, valueRepl)},
438-
};
596+
static const std::string CountTempl =
597+
"if count == 0 then\n"
598+
" #^#READ#$#\n"
599+
"end\n"
600+
"#^#VALUE#$#\n"
601+
;
439602

440-
return util::genProcessTemplate(FixedCountTempl, fixedCountRepl);
441-
}
603+
util::GenReplacementMap countRepl = {
604+
{"READ", util::genProcessTemplate(ReadTempl, readRepl)},
605+
{"VALUE", util::genProcessTemplate(ValueTempl, valueRepl)},
606+
};
442607

443-
// TODO:
444-
return "-- TODO: not implemented";
608+
return util::genProcessTemplate(CountTempl, countRepl);
445609
}
446610

447611
} // namespace commsdsl2wireshark

app/commsdsl2wireshark/src/WiresharkListField.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class WiresharkListField final : public commsdsl::gen::GenListField, public Wire
6363
std::string wiresharkDissectElemCodeInternal() const;
6464
std::string wiresharkFixedCountDissectInternal() const;
6565
std::string wiresharkCountPrefixDissectInternal() const;
66+
std::string wiresharkLengthPrefixDissectInternal() const;
67+
std::string wiresharkTermSuffixDissectInternal() const;
6668
std::string wiresharkElemLimitCodeInternal() const;
6769

6870
std::vector<WiresharkField*> m_wiresharkFields;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import sys
2+
3+
from commsdsl_pcap_gen import *
4+
5+
def do_frame(id, payload):
6+
prefix = struct.pack('!B', id)
7+
return prefix + payload
8+
9+
def pcap1(f):
10+
seq = 1
11+
payload = struct.pack('>5IB2IBBIBIBBII', *([0x11111111] * 5), 2, *([0x22222222] * 2), 10, *([4, 0x33333333] * 2), 9, 4, *([0x44444444] * 2),)
12+
msg1 = do_frame(1, payload)
13+
header = commsdsl_create_ethernet_ip_tcp_headers(len(msg1), seq)
14+
commsdsl_write_packet(f, header + msg1, time.time())
15+
16+
def pcap2(f):
17+
seq = 2000
18+
payload1 = struct.pack('>6s4sB', b"hello\x00", b"bla\x00", 0)
19+
payload2 = struct.pack('>2s2sB', b"a\x00", b"b\x00", 0)
20+
msg2_1 = do_frame(2, payload1)
21+
msg2_2 = do_frame(2, payload2)
22+
header = commsdsl_create_ethernet_ip_tcp_headers(len(msg2_1) + len(msg2_2), seq)
23+
commsdsl_write_packet(f, header + msg2_1 + msg2_2, time.time())
24+
25+
def main():
26+
with open(sys.argv[1], 'wb') as f:
27+
commsdsl_write_pcap_header(f)
28+
pcap1(f)
29+
pcap2(f)
30+
31+
if __name__ == '__main__':
32+
main()

0 commit comments

Comments
 (0)