Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Packet analysis with mruby on Wireshark - dRuby as example

Packet analysis with mruby on Wireshark - dRuby as example

More Decks by Misaki Shioi(塩井美咲/しおい)

Other Decks in Programming

Transcript

  1. .JTBLJ4IJPJ !TIJPJNN!DPF@  4FQ  3VCZ,BJHJ 1BDLFUBOBMZTJTXJUINSVCZPO8JSFTIBSL E3VCZBTFYBNQMF

  2. "CPVUNF (JU)VC!TIJPJNN 5XJUUFS!DPF@ 8FCBQQMJDBUJPOEFWFMPQFS .FNCFSPG"TBLVTBSC'VLVPLBSC 8BTBTQFBLFSBU3VCZ,BJHJ5BLFPVU 5PZDPM%F fi OFZPVSPXOBQQMJDBUJPOQSPUPDPM IUUQTSVCZLBJHJPSHUBLFPVUQSFTFOUBUJPOTDPF@IUNM

  3. "OE*BNJOUFSFTUFEJODPNQVUFSOFUXPSLT BOEBNBIPCCZVTFSPG8JSFTIBSL

  4. "CPVU8JSFTIBSL 8JSFTIBSLJTBXJEFMZVTFEOFUXPSLQBDLFUBOBMZ[FS ŠŠŠ "OFUXPSLQBDLFUBOBMZ[FSJTʜ 4PGUXBSFUPBOBMZ[FQBDLFUT fl PXJOHPWFSBOFUXPSL BOEEJTQMBZUIFNJOIVNBOSFBEBCMFGPSNBU

  5. "CPVU8JSFTIBSL 3FGIUUQTVQMPBEXJLJNFEJBPSHXJLJQFEJBDPNNPOTDDG8JSFTIBSL@@TDSFFOTIPUQOH

  6. "CPVU8JSFTIBSL 3FGIUUQTVQMPBEXJLJNFEJBPSHXJLJQFEJBDPNNPOTDDG8JSFTIBSL@@TDSFFOTIPUQOH 5IFl1BDLFU%FUBJMTzQBOF 5IFl1BDLFU#ZUFTzQBOF 5IFl1BDLFU-JTUzQBOF

  7. 8JSFTIBSLTVQQPSUTNBOZDPNNPOOFUXPSL QSPUPDPMTCZEFGBVMU FH&UIFSOFU** *1 5$1 %/4 5-4 26*$ )551ʜ 1BDLFUBOBMZTJTXJUIQSPUPDPMEJTTFDUPST

  8. 5PBOBMZ[FQBDLFUTGPSUIFTFQSPUPDPMT  8JSFTIBSLIBTCVJMUJONPEVMFTGPSFBDIPGUIFN  XIJDIBSFDBMMFElQSPUPDPMEJTTFDUPSTz 1BDLFUBOBMZTJTXJUIQSPUPDPMEJTTFDUPST

  9. 28IBUJG*XBOUUPBOBMZ[FQBDLFUTGPSBQSPUPDPM UIBU8JSFTIBSLEPFTOPUTVQQPSUCZEFGBVMU  ":PVDBODSFBUFZPVSPSJHJOBMEJTTFDUPS BOEJODMVEFJUJOUP8JSFTIBSL UPBOBMZ[FQBDLFUTGPSUIBUQSPUPDPM

  10. 28IBUJG*XBOUUPBOBMZ[FQBDLFUTGPSBQSPUPDPM UIBU8JSFTIBSLEPFTOPUTVQQPSUCZEFGBVMU  ":PVDBODSFBUFZPVSPXOEJTTFDUPS BOEJODMVEFJUJOUP8JSFTIBSL UPBOBMZ[FQBDLFUTGPSUIBUQSPUPDPM

  11. 8JSFTIBSL%FWFMPQFST(VJEFJODMVEFTBUVUPSJBMGPS EFWFMPQJOHZPVSPXOEJTTFDUPS 'PSEFWFMPQJOHZPVSPXOEJTTFDUPST IUUQTXXXXJSFTIBSLPSHEPDTXTEH@IUNM@DIVOLFE$IBQUFS%JTTFDUJPOIUNM

  12. 'PSFYBNQMF IFSFJTBQSPUPDPMOBNFE'PP 'PPQBDLFUIBTBTUSVDUVSFJOUIJTGPSNBU 'PSEFWFMPQJOHZPVSPXOEJTTFDUPST Y Y Y Y YG Y

    Y Y 5ZQF 'MBHT 4FRVFODF/VNCFS *OJUJBM*1"EESFTT IUUQTXXXXJSFTIBSLPSHEPDTXTEH@IUNM@DIVOLFE$IBQUFS%JTTFDUJPOIUNM
  13. #include "con fi g.h" #include <epan/packet.h> #de fi ne FOO_PORT

    30000 static int proto_foo = -1; static int hf_foo_pdu_type = -1; static int hf_foo_ fl ags = -1; static int hf_foo_sequenceno = -1; static int hf_foo_initialip = -1; static gint ett_foo = -1; static const value_string packettypenames[] = { { 1, "Initialise" }, { 2, "Terminate" }, { 3, "Data" }, { 0, NULL } }; static int dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO"); col_clear(pinfo->cinfo,COL_INFO); proto_item *ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA); proto_tree *foo_tree = proto_item_add_subtree(ti, ett_foo); gint offset = 0; proto_tree_add_item(foo_tree, hf_foo_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(foo_tree, hf_foo_ fl ags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(foo_tree, hf_foo_sequenceno, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(foo_tree, hf_foo_initialip, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; return tvb_captured_length(tvb); } void proto_register_foo(void) { static hf_register_info hf[] = { { &hf_foo_pdu_type, { "FOO PDU Type", "foo.type", FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0, NULL, HFILL } }, //… }; static gint *ett[] = { &ett_foo }; proto_foo = proto_register_protocol("FOO Protocol", "FOO", "foo"); proto_register_ fi eld_array(proto_foo, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_foo(void) { static dissector_handle_t foo_handle = create_dissector_handle(dissect_foo, proto_foo); dissector_add_uint("tcp.port", FOO_PORT, foo_handle); } 'PSEFWFMPQJOHZPVSPXOEJTTFDUPST IUUQTXXXXJSFTIBSLPSHEPDTXTEH@IUNM@DIVOLFE$IBQUFS%JTTFDUJPOIUNM 'PMMPXJOHUIF8JSFTIBSLUVUPSJBM ZPVDBOEFWFMPQBEJTTFDUPS UPBOBMZ[F'PPQSPUPDPMQBDLFUTMJLFUIJT
  14. #ZJODMVEJOHUIJT'PPEJTTFDUPSJOUP8JSFTIBSL  UIF'PPQSPUPDPMQBDLFUDBOCFBOBMZ[FEMJLFUIJT 'PSEFWFMPQJOHZPVSPXOEJTTFDUPST IUUQTXXXXJSFTIBSLPSHEPDTXTEH@IUNM@DIVOLFE$IBQUFS%JTTFDUJPOIUNM 5ZQF 'MBHT 4FRVFODF/VNCFS *OJUJBM*1"EESFTT

  15. $VSSFOUMZ  8JSFTIBSLQSPWJEFT"1*TUPEFWFMPQEJTTFDUPST JO-VBBOE$POMZ *U`TBMJUUMFEJTBQQPJOUJOHGPSVT3VCZJTUT  XFDBOOPUXSJUF3VCZGPSEFWFMPQJOHEJTTFDUPSTʜ

  16. 4P *DSFBUFEBOFYUFOEFE8JSFTIBSL UIBUBMMPXTZPVUPEFWFMPQBEJTTFDUPSJO3VCZ CZFNCFEEJOHNSVCZJOUP8JSFTIBSL ɹTIJPJNNXJSFTIBSL@XJUI@NSVCZ ɹIUUQTHJUIVCDPNTIJPJNNXJSFTIBSL@XJUI@NSVCZ

  17. 5PEBZ`TBHFOEB )PXUPEFWFMPQBEJTTFDUPSJO3VCZ *NQMFNFOUJOHFYUFOEFE8JSFTIBSLXJUINSVCZ 5SZUPBOBMZ[FE3VCZQBDLFUT

  18. )PXUPEFWFMPQBEJTTFDUPSJO3VCZ

  19. 'JSTU  MFUNFTIPXZPVIPXB8JSFTIBSLEJTTFDUPSXPSLT

  20. 5IFSFBSF PSNPSF UJNFTXIFOBEJTTFDUPSXPSLT 8IFO8JSFTIBSLTUBSUTBOEXIFOUSB ff i DJTPDDVSSFE )PXEPFTB8JSFTIBSLEJTTFDUPSXPSL ᶃ8IFO8JSFTIBSLTUBSUT 

    ɹBEJTTFDUPSJTSFHJTUFSFEJOUPJU ᶄ8IFOUSB ff i DJTPDDVSSFE  ɹBEJTTFDUPSBOBMZ[FTUIFQBDLFU
  21. "EJTTFDUPSJTSFHJTUFSFEJOUP8JSFTIBSLXJUI UIFQSPUPDPMJOGPSNBUJPOOFDFTTBSZUPBOBMZ[FQBDLFUT 5IJTJOGPSNBUJPOJODMVEFTBMJTUPGIFBEFS fi FME ᶃ8IFO8JSFTIBSLTUBSUT 'PSFYBNQMF ɾ5IFQSPUPDPM`TOBNF ɾ5SBOTQPSUQSPUPDPMUPVTF ɾ1PSUOVNCFSUPVTF

    ɾ"MJTUPGIFBEFS fi FME
  22. "IFBEFS fi FMEJTBNFUBEBUB TVDIBTMBCFM OVNCFSTPGCZUFTBOEEJTQMBZGPSNBUUIBU IFMQT8JSFTIBSLJOUFSQSFUQBDLFUTDPSSFDUMZ 8IBUJTIFBEFS fi FME static

    hf_register_info hf[] = { { &hf_foo_pdu_type, { "FOO PDU Type”, “foo.type”, FT_UINT8, BASE_DEC, VALS(packettypenames), 0x0, NULL, HFILL } }, // … }, -BCFM /VNCFSTPGCZUFT %JTQMBZGPSNBU 5IFJOGPSNBUJPOEJTQMBZFEJOUIFl1BDLFU%FUBJMTzQBOFJT PSJHJOBUFEGSPNBOBSSBZPGIFBEFS fi FME
  23. 5IFEJTTFDUPSNBQTUIFEBUBJOXIJDIQPTJUJPOJOUIF QBDLFUJTBOBMZ[FEXJUIXIJDIIFBEFS fi FME TUCZUF6TFl5ZQFzIFBEFS fi FME Y Y Y

    Y YG Y Y Y ᶄ8IFOUSB ffi DJTPDDVSSFE
  24. 5IJTBMMPXT8JSFTIBSLUPBOBMZ[FUIFEBUBDPOUBJOFE JOUIFQBDLFUGPSFBDIQPTJUJPOXIFSFJUJT ᶄ8IFOUSB ffi DJTPDDVSSFE Y Y Y Y YG

    Y Y Y TUCZUF6TFl5ZQFzIFBEFS fi FME
  25. 5PBOBMZ[FQBDLFUTXJUIBEJTTFDUPS  JUSFRVJSFTBUMFBTUUIFGPMMPXJOHGFBUVSFT ɹᶃ3FHJTUFSJOHUIFQSPUPDPMJOGPSNBUJPO  ɹJODMVEJOHBMJTUPGIFBEFS fi FMET ɹᶄ.BQQJOHFBDIEBUBQPTJUJPOJOUIFQBDLFU ɹUPBIFBEFS

    fi FMEUIBUBOBMZ[FTUIBUEBUB 4VNNBSZ
  26. %FWFMPQJOHBEJTTFDUPSJO3VCZBMTPSFRVJSFT UIFTFGFBUVSFT 4PUIFEJTTFDUPSEFWFMPQNFOUJO3VCZJTBTGPMMPXT

  27. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end %FWFMPQBEJTTFDUPSJO3VCZ "EJTTFDUPSJO3VCZDBOCFXSJUUFO JOBDPO fi HVSBUJPO fi MFMJLF%4- QMVHJOTFQBOGPPDPO fi HGPPSC
  28. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end %FWFMPQBEJTTFDUPSJO3VCZ 841SPUPDPMDPO fi HVSF $BMM841SPUPDPMDPO fi HVSFUPEFWFMPQBEJTTFDUPS 5IFSFBSFTFDUJPOTJOUIJTCMPDL QMVHJOTFQBOGPPDPO fi HGPPSC
  29. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end %FWFMPQBEJTTFDUPSJO3VCZ ᶃ3FHJTUFSTFDUJPO ᶄ%JTTFDUPSTFDUJPO QMVHJOTFQBOGPPDPO fi HGPPSC
  30. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end ᶃ3FHJTUFSTFDUJPO 5IFSFHJTUFSTFDUJPOJTGPSSFHJTUFSJOH UIFQSPUPDPMJOGPSNBUJPOGPSBOBMZ[JOHQBDLFUT QMVHJOTFQBOGPPDPO fi HGPPSC
  31. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end -BCFM /VNCFSTPGCZUFT %JTQMBZGPSNBU ᶃ3FHJTUFSTFDUJPO 841SPUPDPMIFBEFSTSFHJTUFSTBMJTUPGIFBEFS  fi FMETCZSFDFJWJOHBOBSSBZPGIBTIFTPGIFBEFS  fi FMET QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMIFBEFST
  32. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end ᶄ%JTTFDUPSTFDUJPO 5IFEJTTFDUPSTFDUJPOJTGPSNBQQJOHFBDIEBUB QPTJUJPOJOUIFQBDLFUUPBIFBEFS fi FME QMVHJOTFQBOGPPDPO fi HGPPSC
  33. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end ᶄ%JTTFDUPSTFDUJPO 5IFEJTTFDUPSTFDUJPOJTJOTJEF UIFCMPDLPG841SPUPDPMEJTTFDUPST QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMEJTTFDUPST
  34. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end )FBEFS fi FME 1PTJUJPO ᶄ%JTTFDUPSTFDUJPO 84%JTTFDUPSJUFNTSFDFJWFTBOBSSBZPGIBTIFTPG BNBQQJOHCFUXFFOBEBUBQPTJUJPOBOEBIFBEFS fi FME QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMJUFNT
  35. 5IF'PPEJTTFDUPSJO3VCZBMTPDBOBOBMZ[F 'PPQSPUPDPMQBDLFUT 'PPEJTTFDUPSJO3VCZ

  36. &YUFOEFE8JSFTIBSLIBTPUIFSVTFGVMGFBUVSFT  XIJDI*XJMMTIPXZPV

  37. WSProtocol.con fi gure(“Foo") do # … dissectors do items [{

    header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] sub(“Foo Subtree“) do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end end 841SPUPDPMTVC 84%JTTFDUPSTVCDBOEJTQMBZUIFBOBMZTJTSFTVMUT BTBTVCUSFFJOUIFl1BDLFU%FUBJMTzQBOF QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMTVC
  38. WSProtocol.con fi gure(“Foo") do # … dissectors do items [{

    header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] sub(“Foo Subtree (1)“) do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] sub(“Foo Subtree (2)“) do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end end end $BMMJOH841SPUPDPMTVCXJUIJO841SPUPDPMTVC DBOEJTQMBZBEEJUJPOBMTVCUSFFTXJUIJOBTVCUSFF 841SPUPDPMTVC QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMTVC 841SPUPDPMTVC
  39. WSProtocol.con fi gure(“Foo") do # … puts "WSProtocol#value_at(0) - #{value_at(0)}”

    puts "WSProtocol#value_at(0) - #{value_at(4)}" dissectors do puts "WSDissector#value_at(0) - #{value_at(0)}” puts "WSDissector#value_at(0) - #{value_at(4)}” # … end end 841SPUPDPMWBMVF@BU84%JTTFDUPSWBMVF@BU 841SPUPDPMWBMVF@BUBMMPXTUIFEBUBBUUIF TQFDJ fi FEQPTJUJPOJOUIFQBDLFUUPCFPCUBJOFE BTBIFYBEFDJNBMOVNCFS 4USJOHPCKFDU  QMVHJOTFQBOGPPDPO fi HGPPSC 841SPUPDPMWBMVF@BU 84%JTTFDUPSWBMVF@BU
  40. WSProtocol.con fi gure(“Foo") do transport :tcp port 4567 fi lter

    "proto_foo" headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end 6TFGVMDPOTUBOUTCBTFEPO$  'JFMEUZQFT '5@6*/5  *OUFHSBMUZQFT #"4&@%&$  .BDSP &/$@#*(@&/%*"/ 4PNFPGUIFNBDSPTBOEFOVNOBNFTUIBU 8JSFTIBSLQSPWJEFTGPSEJTTFDUPSEFWFMPQNFOU BSFBWBJMBCMFBTDPOTUBOUTJOUIJTDPO fi H fi MF QMVHJOTFQBOGPPDPO fi HGPPSC
  41. *NQMFNFOUJOH FYUFOEFE8JSFTIBSLXJUINSVCZ

  42. *OPSEFSUPEFWFMPQBEJTTFDUPSJO3VCZ CFIBWJPSTOFFE UPCFCVJMUJOUP8JSFTIBSL ᶄ%JTTFDUPSNVTUMPBEUIFDPO fi H fi MF ɹXIFO8JSFTIBSLTUBSUT 8IBUBSFOFFEFEJOFYUFOEFE8JSFTIBSL

    ᶃ8JSFTIBSLNVTULOPX ɹIPXUPJOUFSQSFU3VCZDPEFT Ruby Ruby
  43. 8JSFTIBSLJTEFWFMPQFEQSJNBSJMZJO$ BOECZEFGBVMUDBOOPUJOUFSQSFU3VCZ 5PBMMPX8JSFTIBSLUPEPTP  NSVCZNVTUCFFNCFEEFEJOUPJU ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT

  44. * fi STUGPSLFEUIF8JSFTIBSLSFQPTJUPSZBOEBEEFE UIFNSVCZSFQPTJUPSZBTB(JUTVCNPEVMFUPJU )FSF ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT

  45. 8JSFTIBSLVTFT$.BLFUPHFOFSBUF.BLF fi MFTGPSCVJMEJOH 4P*BEEFEB fi MF 'JOE.36#:DNBLFUIBU8JSFTIBSLDBO fi OE NSVCZBTBQBDLBHFXIFO$.BLFJTSVO

    ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT fi nd_path(MRUBY_INCLUDE_DIR mruby.h PATHS "${CMAKE_SOURCE_DIR}/mruby/include" NO_DEFAULT_PATH) fi nd_library(MRUBY_LIBRARY NAMES mruby PATHS “${CMAKE_SOURCE_DIR}/mruby/host" PATH_SUFFIXES lib NO_DEFAULT_PATH) include(FindPackageHandleStandardArgs) fi nd_package_handle_standard_args(MRUBY REQUIRED_VARS MRUBY_LIBRARY MRUBY_INCLUDE_DIR 300 VERSION_VAR 300) set(MRUBY_LIBRARIES "${MRUBY_LIBRARY}") set(MRUBY_INCLUDE_DIRS ${MRUBY_INCLUDE_DIR} ) # … DNBLFNPEVMFT'JOE.36#:DNBLF
  46. 8JSFTIBSLVTFTJUTPXONBDSPXT@ fi OE@QBDLBHFUPTFBSDIGPS MJCSBSJFTXIFO$.BLFJTSVO 4P*VTFEUIJTNBDSPUPBEENSVCZUPUIFTFBSDIUBSHFU JO$.BLF-JTUTUYU ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT # ws_ fi

    nd_package(<PackageName> # <CMakeOptions.txt boolean variable> # <cmakecon fi g.h.in macro de fi nition> # [remaining fi nd_package() arguments]) ws_ fi nd_package(MRUBY ENABLE_MRUBY HAVE_MRUBY ) $.BLF-JTUTUYU option(ENABLE_MRUBY "Build with mruby dissector support" ON) $.BLF0QUJPOTUYU #cmakede fi ne HAVE_MRUBY 1 $.BLF0QUJPOTUYU
  47. 5IFO TQFDJGZUIBUUIFEJTTFDUPSBCPVUUPEFWFMPQMJOLT NSVCZXIFOCVJMEJOH8JSFTIBSL 5IJTXJMMCFEFTDSJCFEJOUIF$.BLF-JTUTUYUGPSUIFEJTTFDUPS ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT include(WiresharkPlugin) set_module_info(foo 0 0 1

    0) # … add_wireshark_plugin_library(protofoo epan) target_include_directories(foo PRIVATE ${MRUBY_INCLUDE_DIRS}) target_link_libraries(foo epan ${MRUBY_LIBRARIES}) install_plugin(foo epan) # … QMVHJOTFQBOQSPUPGPP$.BLF-JTUTUYU
  48. #include "con fi g.h" #include <epan/packet.h> #include <mruby.h> #include <mruby/compile.h>

    # … void proto_reg_handoff_protofoo(void) { mrb_state *mrb = mrb_open(); mrb_load_string(mrb, “puts ‘Hello from mruby’”); mrb_close(mrb); } ʜOPXTVDDFTTGVMMZSVO3VCZDPEF ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT )FBEFS fi MFTPGNSVCZ 3VCZDPEF 5IFO CZJODMVEJOHUIFNSVCZIFBEFS fi MFTJOUP UIFTPVSDFDPEFPGUIJTEJTTFDUPS BOEXSJUF3VCZDPEFT QMVHJOTFQBOGPPQBDLFUGPPD
  49. #include "con fi g.h" #include <epan/packet.h> #include <mruby.h> #include <mruby/compile.h>

    # … void proto_reg_handoff_protofoo(void) { mrb_state *mrb = mrb_open(); mrb_load_string(mrb, “puts ‘Hello from mruby’”); mrb_close(mrb); } ᶃ8JSFTIBSLNVTULOPXIPXUPJOUFSQSFU3VCZDPEFT ʜOPXTVDDFTTGVMMZSVO3VCZDPEFJO8JSFTIBSL QMVHJOTFQBOGPPQBDLFUGPPD
  50. /PX UIFOFYUTUFQJTUPBMMPXUIFEJTTFDUPSUPMPBE UIFDPO fi H fi MFXIFO8JSFTIBSLTUBSUT ᶄ.VTUCFBCMFUPMPBEUIFDPO fi H

    fi MF
  51. 8IFO8JSFTIBSLTUBSUT UIFEJTTFDUPSBMXBZTDBMMT BGVODUJPODBMMFElUIFIBOEP ff GVODUJPOz *OUIFIBOEP ff GVODUJPO DBMMBGVODUJPOXIJDIJTOBNFE NSC@XT@QSPUPDPM@TUBSU

    UIBUMPBETUIFDPO fi H fi MF ᶄ.VTUCFBCMFUPMPBEUIFDPO fi H fi MF The handoff function mrb_ws_protocol_start() WSProtocol.con fi gure(“Foo") do … headers […] dissectors do items [ … ] end end
  52. #include "con fi g.h" #include <epan/packet.h> #include "../plugins/epan/mruby/ws_protocol.c" # …

    void proto_reg_handoff_protofoo(void) { mrb_ws_protocol_start(“../plugins/epan/protofoo/con fi g.foo.rb”); } 5IFIBOEP ff GVODUJPO 5IFIBOEP ff GVODUJPO 5IFIBOEP ff GVODUJPOJTXSJUUFOJOUIFEJTTFDUPS *UTJNQMZDBMMTNSC@XT@QSPUPDPM@TUBSU QBTTJOH UIFQBUIUPUIFDPO fi H fi MF WSProtocol.con fi gure(“Foo") do … headers […] dissectors do items [ … ] end end $BMMNSC@XT@QSPUPDPM@TUBSU QMVHJOTFQBOGPPQBDLFUQSPUPGPPD
  53. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } NSC@XT@QSPUPDPM@TUBSU NSC@XT@QSPUPDPM@TUBSU QFSGPSNTJOJUJBMJ[BUJPO  TVDIBTEF fi OJOHBDMBTTXJUINFUIPETGPSUIF%4-T "OEUIFOJUMPBETUIFDPO fi H fi MF
  54. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } typedef enum { REGISTRATION, DISSECTION, } OperationMode; "UUIJTQPJOUXIFO8JSFTIBSLJTTUBSUFE UIJTDPEF GPSFYUFOTJPOJTPQFSBUJOHJO3&(*453"5*0/NPEF 3&(*453"5*0/NPEF NSC@XT@QSPUPDPM@TUBSU
  55. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } "HMPCBMWBSJBCMFUPTUPSFOFXNSC@TUBUF $SFBUFOFXNSC@TUBUFBOETUPSFJU 'JSTU DSFBUFBOFXNSC@TUBUFBOETUPSFJUJOUP BHMPCBMWBSJBCMF NSC@XT@QSPUPDPM@TUBSU
  56. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } /FYU TUPSFUIFQBUIUPUIFDPO fi H fi MFJOUP BHMPCBMWBSJBCMF 4UPSFUIFQBUIUPUIFDPO fi H fi MF NSC@XT@QSPUPDPM@TUBSU "HMPCBMWBSJBCMFUPTUPSFUIFQBUI
  57. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } *OUIJTXBZ JUXJMMCFQPTTJCMFUPSFTUPSFUIFN MBUFS XIFOUSB ffi DJTPDDVSSFEMBUFS NSC@XT@QSPUPDPM@TUBSU
  58. static int operation_mode = REGISTRATION; static mrb_state *_mrb; char con

    fi g_src_path[256]; mrb_value mrb_ws_protocol_start(const char *pathname) { if (operation_mode != REGISTRATION) perror(“…”); exit(1); _mrb = mrb_open(); strcpy(con fi g_src_path, pathname); // … FILE *con fi g_src = fopen(con fi g_src_path, "r"); return mrb_load_ fi le(_mrb, con fi g_src); } 5IFOUIFDPO fi H fi MFJTMPBEFE NSC@XT@QSPUPDPM@TUBSU -PBEUIFDPO fi H fi MF
  59. /PX XIFOUIFDPO fi H fi MFJTMPBEFE  UIFO841SPUPDPMDPO fi HVSFJTFYFDVUFE

    841SPUPDPMDPO fi HVSF The handoff function mrb_ws_protocol_start() WSProtocol.con fi gure(“Foo") do … headers […] dissectors do items [ … ] end end
  60. static mrb_value mrb_ws_protocol_con fi g(mrb_state *mrb, mrb_value self) { mrb_value

    name, block; mrb_get_args(mrb, "S&", &name, &block); mrb_value proto = mrb_funcall(mrb, self, "new", 1, name); mrb_funcall_with_block(mrb, proto, mrb_intern_lit(mrb, "instance_eval"), 0, NULL, block); mrb_value mrb_con fi g = mrb_nil_value(); if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); return mrb_con fi g; } if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); NSC@XT@QSPUPDPM@DPO fi H 841SPUPDPMDPO fi HVSFDBMMT UIF$GVODUJPONSC@XT@QSPUPDPM@DPO fi H 
  61. static mrb_value mrb_ws_protocol_con fi g(mrb_state *mrb, mrb_value self) { mrb_value

    name, block; mrb_get_args(mrb, "S&", &name, &block); mrb_value proto = mrb_funcall(mrb, self, "new", 1, name); mrb_funcall_with_block(mrb, proto, mrb_intern_lit(mrb, "instance_eval"), 0, NULL, block); mrb_value mrb_con fi g = mrb_nil_value(); if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); return mrb_con fi g; } if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); 5IJTGVODUJPOJOTUBOUJBUFT841SPUPDPMDMBTTBOE FYFDVUFTBCMPDLPGDPO fi HVSFXJUIJOTUBODF@FWBM &YFDVUF841SPUPDPMOFX &YFDVUF#BTJD0CKFDUJOTUBODF@FWBM NSC@XT@QSPUPDPM@DPO fi H
  62. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end 5IFOJOUIFSFHJTUFSTFDUJPOPGUIFCMPDL  3FHJTUFSTFDUJPO 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF
  63. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end 5IFQSPUPDPMJOGPSNBUJPO  JODMVEJOHUIFMJTUPGIFBEFS fi FMET BSFTUPSFEJO JOTUBODFWBSJBCMFTPGUIF841SPUPDPMJOTUBODF 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF !USBOTQPSU !QPSU ! fi MUFS !IFBEFST !OBNF
  64. static mrb_value mrb_ws_protocol_con fi g(mrb_state *mrb, mrb_value self) { mrb_value

    name, block; mrb_get_args(mrb, "S&", &name, &block); mrb_value proto = mrb_funcall(mrb, self, "new", 1, name); mrb_funcall_with_block(mrb, proto, mrb_intern_lit(mrb, "instance_eval"), 0, NULL, block); mrb_value mrb_con fi g = mrb_nil_value(); if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); return mrb_con fi g; } if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); "GUFSUIFCMPDL fi OJTIFTFYFDVUJOH  JUSFUVSOTUPUIFNSC@XT@QSPUPDPM@DPO fi H  NSC@XT@QSPUPDPM@DPO fi H BHBJO
  65. static mrb_value mrb_ws_protocol_con fi g(mrb_state *mrb, mrb_value self) { mrb_value

    name, block; mrb_get_args(mrb, "S&", &name, &block); mrb_value proto = mrb_funcall(mrb, self, "new", 1, name); mrb_funcall_with_block(mrb, proto, mrb_intern_lit(mrb, "instance_eval"), 0, NULL, block); mrb_value mrb_con fi g = mrb_nil_value(); if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); return mrb_con fi g; } if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); *O3&(*453"5*0/NPEF  841SPUPDPMSFHJTUFSJTUIFODBMMFE NSC@XT@QSPUPDPM@DPO fi H BHBJO $BMM841SPUPDPMSFHJTUFS
  66. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name, ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS 841SPUPDPMSFHJTUFSDBMMT B$GVODUJPOXT@QSPUPDPM@SFHJTUFS 
  67. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name, ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS 5IJTGVODUJPOQMBZTBOJNQPSUBOUSPMFJO SFHJTUFSJOHQSPUPDPMJOGPSNBUJPOXJUI8JSFTIBSL
  68. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name, ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS *OXT@QSPUPDPM@SFHJTUFS  XT@QSPUPDPM@TFU@NFNCFST JTDBMMFEBU fi STU $BMMXT@QSPUPDPM@TFU@NFNCFST 
  69. static void ws_protocol_set_members(mrb_state *mrb, mrb_value self) { mrb_value mrb_name =

    mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name")); mrb_value mrb_transport = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@transport")); mrb_value mrb_port = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@port")); mrb_value mrb_ fi lter = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ fi lter")); strcpy(ws_protocol.name, mrb_string_cstr(mrb, mrb_name)); strcpy(ws_protocol. fi lter, mrb_string_cstr(mrb, mrb_ fi lter)); strcpy(ws_protocol.transport, mrb_string_cstr(mrb, mrb_funcall(mrb, mrb_transport, "to_s", 0))); ws_protocol.port = (unsigned int)mrb_ fi xnum(mrb_port); } XT@QSPUPDPM@TFU@NFNCFST XT@QSPUPDPM@TFU@NFNCFST SFTUPSFT UIFQSPUPDPMJOGPSNBUJPO PUIFSUIBOIFBEFS fi FMET TUPSFEJOUIF841SPUPDPMJOTUBODF !USBOTQPSU !QPSU ! fi MUFS !OBNF
  70. static void ws_protocol_set_members(mrb_state *mrb, mrb_value self) { mrb_value mrb_name =

    mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name")); mrb_value mrb_transport = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@transport")); mrb_value mrb_port = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@port")); mrb_value mrb_ fi lter = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ fi lter")); strcpy(ws_protocol.name, mrb_string_cstr(mrb, mrb_name)); strcpy(ws_protocol. fi lter, mrb_string_cstr(mrb, mrb_ fi lter)); strcpy(ws_protocol.transport, mrb_string_cstr(mrb, mrb_funcall(mrb, mrb_transport, "to_s", 0))); ws_protocol.port = (unsigned int)mrb_ fi xnum(mrb_port); } XT@QSPUPDPM@TFU@NFNCFST 5IFODPQJFTUIFNJOUPHMPCBMWBSJBCMFT
  71. static void ws_protocol_set_members(mrb_state *mrb, mrb_value self) { mrb_value mrb_name =

    mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name")); mrb_value mrb_transport = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@transport")); mrb_value mrb_port = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@port")); mrb_value mrb_ fi lter = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@ fi lter")); strcpy(ws_protocol.name, mrb_string_cstr(mrb, mrb_name)); strcpy(ws_protocol. fi lter, mrb_string_cstr(mrb, mrb_ fi lter)); strcpy(ws_protocol.transport, mrb_string_cstr(mrb, mrb_funcall(mrb, mrb_transport, "to_s", 0))); ws_protocol.port = (unsigned int)mrb_ fi xnum(mrb_port); } XT@QSPUPDPM@TFU@NFNCFST *OUIJTXBZ 8JSFTIBSLDBOSFTUPSFUIFNGSPN UIFHMPCBMWBSJBCMFTBOEIBOEMFUIFN
  72. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO "GUFSFYFDVUJOHXT@QSPUPDPM@TFU@NFNCFST  JUSFUVSOTUPUIFXT@QSPUPDPM@SFHJTUFS 
  73. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO 5IFOXT@QSPUPDPM@SFHJTUFS SFTUPSFBOBSSBZPG IFBEFS fi FMETTUPSFEJOUIF841SPUPDPMJOTUBODF 0CUBJOBOBSSBZPGIFBEFS fi FMET
  74. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO BOEBMMPDBUFTIFBQNFNPSZGPSUIFBSSBZPG IFBEFS fi FMETXJUINBMMPD  6TFNBMMPD 
  75. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO 5IFJUFNTPGUIFIFBEFS fi FMETBSSBZBSFTUPSFE JOUIFIFBQNFNPSZ -PPQUPTUPSFUIFIFBEFS fi FMET
  76. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO *OUIJTXBZ 8JSFTIBSLDBOSFTUPSFUIFNGSPN UIFIFBQNFNPSZBOEIBOEMFUIFN
  77. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO /FYU DBMMQSPUP@SFHJTUFS@QSPUPDPM UPSFHJTUFS UIFQSPUPDPMJOGPSNBUJPOPUIFSUIBOUIFIFBEFS fi FMET 3FHJTUFSQSPUPDPMJOGPSNBUJPOPUIFSUIBOIFBEFS fi FMET \\ Here is the climax of this function!! //
  78. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO 'JOBMMZ DBMMQSPUP@SFHJTUFS@ fi FME@BSSBZ UPSFHJTUFS UIFIFBEFS fi FMET 3FHJTUFSIFBEFS fi FMET \\ Here is the climax of this function!! //
  79. static void ws_protocol_register(mrb_state *mrb, mrb_value self) { ws_protocol_set_members(mrb, self); mrb_value

    mrb_hfs = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@headers")); ws_hfs.size = (int)RARRAY_LEN(mrb_hfs); hf_register_info *hf = malloc(sizeof(hf_register_info) * ws_hfs.size); for (int i = 0; i < ws_hfs.size; i++) { hf[i].p_id = &ws_hfs.headers[i].handle; // ... } // ... phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); proto_register_ fi eld_array(phandle, hf, ws_hfs.size); proto_register_subtree_array((gint *const *)ett, (int)mrb_ fi xnum(mrb_dissector_depth)); } phandle = proto_register_protocol(ws_protocol.name, ws_protocol.name,ws_protocol. fi lter); XT@QSPUPDPM@SFHJTUFS BHBJO 5IJTDPNQMFUFTXIBUJTEPOFCZFYFDVUJOH UIFDPO fi H fi MF
  80. #include "con fi g.h" #include <epan/packet.h> #include "../plugins/epan/mruby/ws_protocol.c" # …

    void proto_reg_handoff_protofoo(void) { mrb_ws_protocol_start(“../plugins/epan/protofoo/con fi g.foo.rb”); } 5IFIBOEP ff GVODUJPO 5IJTJTBMMUIBUJTEPOF 5IFIBOEP ff GVODUJPOUIFOEPFTOPUIJOHBOE FYJUTXJUIPVUGVSUIFSBDUJPO 5IFTFBSFUIFEJTTFDUPSTXIBUUPEP XIFO8JSFTIBSLTUBSUT QMVHJOTFQBOGPPQBDLFUQSPUPGPPD
  81. 'JOBMMZ BEEUPUIFFYUFOTJPODPEF XIBUUIFEJTTFDUPSEPXIFOUSB ff i DJTPDDVSSFE 8IFOBUSB ff i DPDDVSSFE

    UIFEJTTFDUPSBMXBZTDBMMT BDBMMCBDLGVODUJPO -FUTBEEUIFSFTUPGXIBUXFXJMMEPJOUIJTGVODUJPO 3FNBJOJOHJTTVFT The callback function
  82. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFDBMMCBDLGVODUJPO 5IFDBMMCBDLGVODUJPO
  83. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFDBMMCBDLGVODUJPO 'JSTU UIFPQFSBUJPONPEFJTDIBOHFE UP%*44&$5*0/IFSF $IBOHFUP%*44&$5*0/NPEF
  84. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); #ZUIFXBZ UIF841SPUPDPMJOTUBODFUIBUXBT KVTUDSFBUFEXIFO8JSFTIBSLTUBSUTJTOPUQFSTJTUFOU  TPJUEJTBQQFBSTBUUIFFOEPGUIFIBOEP ff GVODUJPO 5IFDBMMCBDLGVODUJPO
  85. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); -FU`TDSFBUFUIF841SPUPDPMJOTUBODFBHBJO 5IFDBMMCBDLGVODUJPO
  86. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 6TJOHUIFNSC@TUBUFBOEUIFQBUIUP UIFDPO fi H fi MFTUPSFEJOBHMPCBMWBSJBCMF XIFO8JSFTIBSLTUBSUT MPBEUIFDPO fi H fi MFBHBJO 5IFDBMMCBDLGVODUJPO 6TFUIFNSC@TUBUFUIF fi MFQBUI -PBEUIFDPO fi H fi MFBHBJO
  87. static mrb_value mrb_ws_protocol_con fi g(mrb_state *mrb, mrb_value self) { mrb_value

    name, block; mrb_get_args(mrb, "S&", &name, &block); mrb_value proto = mrb_funcall(mrb, self, "new", 1, name); mrb_funcall_with_block(mrb, proto, mrb_intern_lit(mrb, "instance_eval"), 0, NULL, block); mrb_value mrb_con fi g = mrb_nil_value(); if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); return mrb_con fi g; } if (operation_mode == REGISTERATION) mrb_con fi g = mrb_funcall(mrb, proto, "register!", 0); 5IJTFYFDVUFTNSC@XT@QSPUPDPM@DPO fi H BHBJO  BOEJOTUBOUJBUFT841SPUPDPMDMBTTBOEFYFDVUFT UIFCMPDLPG841SPUPDPMDPO fi HVSFBHBJO NSC@XT@QSPUPDPM@DPO fi H BHBJO &YFDVUF841SPUPDPMOFX &YFDVUF#BTJD0CKFDUJOTUBODF@FWBM
  88. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end %JTTFDUPSTFDUJPO 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF 5IFOJOUIFEJTTFDUPSTFDUJPOPGUIFCMPDL
  89. WSProtocol.con fi gure("Foo") do transport :tcp port 4567 fi lter

    “foo” headers [{ name: :foo_pdu_type, label: "FOO PDU Type", fi lter: "foo.type", type: WSProtocol::FT_UINT8, display: WSProtocol::BASE_DEC, dict: { 1 => "Initialise", 2 => "Terminate", 3 => "Data" } }, … ] dissectors do items [{ header: :foo_pdu_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0 }, … ] end end 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF !EJTTFDUPST 5IFNBQQJOHTPGFBDIEBUBQPTJUJPOJOUIFQBDLFUUP BIFBEFS fi FMEBSFTUPSFEJOJOTUBODFWBSJBCMFTPG UIF841SPUPDPMJOTUBODF
  90. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFO SFUVSOUPUIFDBMMCBDLGVODUJPO 5IFDBMMCBDLGVODUJPOBHBJO
  91. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFJUFNTKVTUTUPSFEJOUIFEJTTFDUPSTFDUJPO BSFSFTUPSFEGSPNUIF841SPUPDPMJOTUBODF 0CUBJOUIFTUPSFENBQQJOHT 5IFDBMMCBDLGVODUJPOBHBJO
  92. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFDBMMCBDLGVODUJPOBHBJO 8JUIUIFTFNBQQJOHT FYFDVUFTBGVODUJPOUIBUEJTQMBZT UIFBOBMZTJTSFTVMUTJOUIF1BDLFU%FUBJMQBOF %JTQMBZUIFBOBMZTJTSFTVMUT \\ Here is the climax of this function!! //
  93. static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void

    *data _U_) { if (operation_mode != DISSECTION) operation_mode = DISSECTION; FILE *con fi g_src = fopen(con fi g_src_path, "r"); mrb_value mrb_con fi g = mrb_load_ fi le(_mrb, con fi g_src); // … mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); mrb_value mrb_items = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, “@items”)); // … proto_tree *main_tree = proto_item_add_subtree(ti, ett); ws_protocol_add_items(_mrb, mrb_items, main_tree, tvb); // … mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); ws_protocol_add_subtree_items(_mrb, mrb_subtrees, main_tree, tvb); // … } static int ws_protocol_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_) mrb_value mrb_subtrees = mrb_iv_get(_mrb, mrb_dfs, mrb_intern_lit(mrb, "@subtrees")); mrb_value mrb_dfs = mrb_iv_get(_mrb, mrb_con fi g, mrb_intern_lit(mrb, "@dissectors")); 5IFDBMMCBDLGVODUJPOBHBJO 5IFBCPWFJTBOJOUSPEVDUJPOUP UIFFYUFOEFE8JSFTIBSLJNQMFNFOUBUJPO
  94. 5SZUPBOBMZ[FE3VCZQBDLFUT

  95. E3VCZ%JTUSJCVUFE3VCZ JTPOFPGTUBOEBSE3VCZMJCSBSJFT *UBMMPXTB3VCZQSPDFTTUPDBMMNFUIPETPOBPCKFDU JOBOZPUIFS3VCZQSPDFTTPOBOZPUIFSIPTU "CPVUE3VCZ

  96. 'PSFYBNQMF  "CPVUE3VCZ A B

  97. 0O" UIF'PPDMBTTBOEHSFFUJOHJOTUBODFNFUIPEBSF EF fi OFE"OEPOFPCKFDUPGUIF'PPDMBTTJTJOTUBOUJBUFE "CPVUE3VCZ class Foo def greeting(name)

    “Hello #{name}” end end foo = Foo.new A B
  98. 1BTTJOHUIJTPCKFDUBOEB63*BTBSHVNFOUTUP %3CTUBSU@TFSWJDFXJMMCJOEUIF'PPPCKFDUUPUIJT63* "CPVUE3VCZ class Foo def greeting(name) “Hello #{name}” end

    end foo = Foo.new DRb.start_service(“druby://…”, foo) A B
  99. 0O# DBMMJOH%3C0CKFDUOFX@XJUI@VSJXJUIUIF63*SFUVSOTB %3C0CKFDUPCKFDUUIBUDBODBMMNFUIPETPOUIF'PPPCKFDU CPVOEUPUIF63* "CPVUE3VCZ class Foo def greeting(name) “Hello

    #{name}” end end foo = Foo.new DRb.start_service(“druby://…”, foo) foo = DRbObject.new_with_uri(“druby://…”) A B
  100. 8IFOHSFFUJOHJTDBMMFEPO# UIJTNFUIPEDBMMJT GPSXBSEFEWJB63*UPUIF'PPPCKFDUPO" "CPVUE3VCZ class Foo def greeting(name) “Hello #{name}”

    end end foo = DRbObject.new_with_uri(“druby://…”) puts foo.greeting(“Wireshark”) foo = Foo.new DRb.start_service(“druby://…”, foo) A B
  101. 5IFO UIFSFUVSOWBMVFPGHSFFUJOHFYFDVUFEPO"JT SFUVSOFEUP#WJB63* "CPVUE3VCZ class Foo def greeting(name) “Hello #{name}”

    end end foo = DRbObject.new_with_uri(“druby://…”) puts foo.greeting(“Wireshark”) > Hello Wireshark foo = Foo.new DRb.start_service(“druby://…”, foo) A B 
  102. 'PSNPSFJOGPSNBUJPO TFF!N@TFLJ`TUBML E3VCZJOUIFMBTUDFOUVSZBU3VCZ,BJHJ IUUQTSVCZLBJHJPSHQSFTFOUBUJPOTN@TFLJIUNM IUUQTXXXZPVUVCFDPNXBUDI W;X5:Y;( "CPVUE3VCZ

  103. /PUFUIBU8JSFTIBSLIBTBCVJMUJO$EJTTFDUPSUIBU BOBMZ[FE3VCZQBDLFUTCZEFGBVMU 4PJGZPVXBOUUPBOBMZ[FE3VCZQBDLFUTSJHIUOPX  ZPVDBOPGDPVSTFVTFUIJTPOFʜ "OBMZ[JOHBE3VCZQBDLFUXJUI8JSFTIBSL

  104. )PXFWFS  *IBWFOPXWFOUVSFEUPEFWFMPQBEJTTFDUPSJO3VCZ UIBUBOBMZ[FTE3VCZQBDLFUT

  105. 5PEFWFMPQBEJTTFDUPS  ZPVOFFEUPLOPXUIFTUSVDUVSFPGUIFQBDLFU ZPVXBOUUPBOBMZ[F -FUTMPPLBUUIFTUSVDUVSFPGBE3VCZQBDLFU

  106. *OUIJTDBTF UIFSFRVFTUQBDLFUJTBDBMMUPHSFFUJOH POUIF'PPPCKFDUGSPN# 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU class Foo def greeting(name) “Hello #{name}”

    end end foo = DRbObject.new_with_uri(“druby://…”) puts foo.greeting(“dRuby”) foo = Foo.new DRb.start_service(“druby://…”, foo) A B
  107. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue raise(DRbConnError, $!.message, $!.backtrace) end # … end # … end 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU 3FRVFTUQBDLFUTBSFTFOUJO %3C.FTTBHFTFOE@SFRVFTU IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC--
  108. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue raise(DRbConnError, $!.message, $!.backtrace) end # … end # … end 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU &BDIEBUBUPCFJOUIFQBDLFUBSFEVNQFEJO .BSTIBMEVNQBOEUIFOXSJUUFOUPUIFTUSFBN BTBTFSJFTPGTUSJOHT 8SJUUFOUPUIFTUSFBN %VNQFEJO.BSTIBMEVNQ IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC--
  109. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue raise(DRbConnError, $!.message, $!.backtrace) end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU  "DUVBMWBMVFTPGUIFEVNQFEEBUB  "SFRVFTUQBDLFUDPOUBJOTLJOETPGEBUB
  110. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue # … end # … end # … end 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 3FG 3FGFSFODFUPJEFOUJGZUIFPCKFDU 
  111. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU .FTTBHF .FUIPEOBNF 
  112. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU "SHVNFOUTMFOHUI /VNCFSPGNFUIPEBSHVNFOUT 
  113. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU "SHVNFOUT "SHVNFOUT "SHVNFOUTMFOHUI 
  114. module DRb # … class DRbMessage # … def send_request(stream,

    ref, msg_id, arg, b) ary = [] ary.push(dump(ref.__drbref)) ary.push(dump(msg_id.id2name)) ary.push(dump(arg.length)) arg.each do |e| ary.push(dump(e)) end ary.push(dump(b)) stream.write(ary.join('')) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFRVFTUQBDLFU #MPDL "OBMZ[JOHWBMVFBTBUZQFGPSTJNQMJDJUZ
  115. *OUIJTDBTF UIFSFTQPOTFQBDLFUJTUIFSFUVSOWBMVFPG HSFFUJOHGPSUIF'PPPCKFDUGSPN"UP# class Foo def greeting(name) “Hello #{name}” end

    end foo = DRbObject.new_with_uri(“druby://…”) puts foo.greeting(“dRuby”) > Hello Wireshark foo = Foo.new DRb.start_service(“druby://…”, foo) 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU A B 
  116. module DRb # … class DRbMessage # … def send_reply(stream,

    succ, result) stream.write(dump(succ) + dump(result, !succ)) rescue raise(DRbConnError, $!.message, $!.backtrace) end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU 3FTQPOTFQBDLFUTBSFTFOUJO %3C.FTTBHFTFOE@SFQMZ
  117. module DRb # … class DRbMessage # … def send_reply(stream,

    succ, result) stream.write(dump(succ) + dump(result, !succ)) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU "SFTQPOTFQBDLFUDPOUBJOTLJOETPGEBUB
  118. module DRb # … class DRbMessage # … def send_reply(stream,

    succ, result) stream.write(dump(succ) + dump(result, !succ)) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU 4VDDFTT 8IFUIFSUIFNFUIPEDBMMXBTTVDDFTTGVMPSOPU 
  119. module DRb # … class DRbMessage # … def send_reply(stream,

    succ, result) stream.write(dump(succ) + dump(result, !succ)) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU 3FTVMU 3FUVSOWBMVF 
  120. #BTFEPOUIFTUSVDUVSF  MFUTDPOTJEFSIPXUPBOBMZ[FUIFE3VCZQBDLFUT

  121. %BUBPVUQVUJO.BSTIBMGPSNBU &BDIQJFDFPGEBUBFYDIBOHFECZE3VCZJTEVNQFE JO.BSTIBMEVNQ 5IFEVNQFEEBUBJODMVEFT JOPSEFSGSPNUIFCFHJOOJOH  UIFTJ[FPGUIFEBUB UIFUZQFPGEBUB BOEUIFBDUVBMWBMVF 4J[FPGEBUB

    5ZQFPGEBUB FH*OUFHFS 4USJOH #PPMʜ IUUQTSVCZEPDPSHDPSFEPDNBSTIBM@SEPDIUNM 7BMVFPGEBUB
  122. "OBMZ[JOHEBUBJO.BSTIBMGPSNBU *OUIJTUJNF *USZUPEFWFMPQBEJTTFDUPSUIBUDBOBOBMZ[FBOE EJTQMBZFBDIEBUBDPOUBJOFEJOUIFTFEVNQFETUSJOHT 4J[FPGEBUB 7BMVFPGEBUB 5ZQFPGEBUB FH*OUFHFS 4USJOH #PPMʜ

  123. "OBMZ[JOHEBUBJO.BSTIBMGPSNBU 'PSUIJTQVSQPTF *XPVMEMJLFUPQSPWJEFEIFBEFS fi FMET ɾ4J[FPGEBUB ɾ5ZQFPGEBUB ɾ*OUFHFSWBMVFPGEBUB ɾ4USJOHWBMVFPGEBUB 4J[FPGEBUB

    7BMVFPGEBUB 5ZQFPGEBUB FH*OUFHFS 4USJOH #PPMʜ
  124. WSProtocol.con fi gure("dRuby") do # … headers [{ name: :hf_druby_size,

    label: "Size", type: WSProtocol::FT_UINT32, … }, { name: :hf_druby_type, label: "Type", type: WSProtocol::FT_UINT8, dict: data_types, … }, { name: :hf_druby_integer, label: "Value", type: WSProtocol::FT_UINT32, … }, { name: :hf_druby_string, label: "Value", type: WSProtocol::FT_STRING, … }] # … end )FBEFS fi FMETPGUIFE3VCZEJTTFDUPS 4J[FPGEBUB 5IJTJTUIFMJTUPGIFBEFS fi FMETGPSE3VCZQBDLFUT 5ZQFPGEBUB *OUFHFSWBMVFPGEBUB 4USJOHWBMVFPGEBUB
  125. #ZUIFXBZ

  126. 5ZQFPGEBUBJO.BSTIBMGPSNBUJTUPPEJ ff i DVMU 5IFEVNQFEEBUBDPOUBJOTBWBMVFNFBOTUIFUZQFPGEBUB #VUKVTUMPPLJOHBUUIJTWBMVF  JUJTOPUDMFBSXIBUUZQFPGEBUBUIJTNFBOTʜ 5ZQFPGEBUB FH*OUFHFS

    4USJOH #PPMʜ
  127. 5ZQFPGEBUBJO.BSTIBMGPSNBUJTUPPEJ ff i DVMU l4USJOH 5USVF **OTUBODFWBSJBCMF 8IBUUIJTWBMVFNFBOTzJTEF fi OFEJOUIF.BSTIBMGPSNBU

  128. 5ZQFPGEBUBJO.BSTIBMGPSNBUJTUPPEJ ff i DVMU      

    #VUBTJUJTOPX UIFWBMVFTJO UIJTVOSFBEBCMFGPSNBUJTEJTQMBZFEJOUIFl1BDLFU%FUBJMTzQBOF
  129. WSProtocol.con fi gure("dRuby") do # … data_types = { "0"

    => "nil", "T" => "true", "F" => "false", "i" => "Integer", ":" => "Symbol", "\"" => "String", "I" => "Instance variable", "[" => "Array", # … } headers [ … { name: :hf_druby_type, label: "Type", type: WSProtocol::FT_UINT8, dict: data_types, … }, … ] # … end "EJDUJPOBSZGPSEJTQMBZJOHUZQFTPGEBUB "EJDUJPOBSZ 4P *QSFQBSFEBEJDUJPOBSZUPHFUUIFBDUVBMUZQFPG EBUBSFGFSSJOHUPUIF.BSTIBMGPSNBUJOUIFDPO fi H fi MF
  130. WSProtocol.con fi gure("dRuby") do # … data_types = { "0"

    => "nil", "T" => "true", "F" => "false", "i" => "Integer", ":" => "Symbol", "\"" => "String", "I" => "Instance variable", "[" => "Array", # … } headers [ … { name: :hf_druby_type, label: "Type", type: WSProtocol::FT_UINT8, dict: data_types, … }, … ] # … end 5IFIFBEFS fi FMEUIBUBOBMZ[FUIFUZQFPGEBUB .BLFUIFIFBEFS fi FMEUIBUBOBMZ[FUIFUZQF PGEBUBUPIBWFUIJTEJDUJPOBSZ "EJDUJPOBSZGPSEJTQMBZJOHUZQFTPGEBUB 5IFEJDUJPOBSZ "EJDUJPOBSZ
  131. WSProtocol.con fi gure("dRuby") do # … data_types = { "0"

    => "nil", "T" => "true", "F" => "false", "i" => "Integer", ":" => "Symbol", "\"" => "String", "I" => "Instance variable", "[" => "Array", # … } headers [ … { name: :hf_druby_type, label: "Type", type: WSProtocol::FT_UINT8, dict: data_types, … }, … ] # … end 8IFOEBUBJTEJTQMBZFEJOUIF1BDLFU%FUBJMTzQBOF  UIFUZQFPGEBUBDBOCFEJTQMBZFEJOBSFBEBCMFGPSNBU "EJDUJPOBSZGPSEJTQMBZJOHUZQFTPGEBUB
  132. WSProtocol.con fi gure("dRuby") do # … data_types = { "0"

    => "nil", "T" => "true", "F" => "false", "i" => "Integer", ":" => "Symbol", "\"" => "String", "I" => "Instance variable", "[" => "Array", # … } headers [ … { name: :hf_druby_type, label: "Type", type: WSProtocol::FT_UINT8, dict: data_types, … }, … ] # … end 5IJTDPNQMFUFTUIFSFHJTUFSTFDUJPO "EJDUJPOBSZGPSEJTQMBZJOHUZQFTPGEBUB
  133. /FYU MFU`TDPOTJEFSBCPVUUIFEJTTFDUPSTFDUJPO

  134. WSProtocol.con fi gure("dRuby") do # … packet_type = druby_types[value_at(6)&.hex&.chr] if

    %w[true false].include?(packet_type) # … else # … end end -FU`TEF fi OFUIFEJTTFDUPSTFDUJPO *TlUSVFzPSlGBMTFz  'JSTU TFFUIFWBMVFJOUIFCZUFGSPN UIFCFHJOOJOHPGUIFQBDLFU *GUIFWBMVFNFBOTlUSVFzPSlGBMTFz
  135. WSProtocol.con fi gure("dRuby") do # … packet_type = druby_types[value_at(6)&.hex&.chr] if

    %w[true false].include?(packet_type) # … else # … end end -FU`TEF fi OFUIFEJTTFDUPSTFDUJPO 3FTQPOTFQBDLFU 3FRVFTUQBDLFU ʜUIFQBDLFUJTBSFTQPOTFQBDLFU  #FDBVTFJUTIPVMECFBSFTVMUPGBNFUIPEDBMM  0UIFSXJTF JUJTBSFRVFTUQBDLFU
  136. WSProtocol.con fi gure("dRuby") do # … packet_type = druby_types[value_at(6)&.hex&.chr] if

    %w[true false].include?(packet_type) dissectors("dRuby Response") do sub("Success") do # … end sub(“Result") do # … end end else # … end end /PX  MFU`TEF fi OFUIFNBQQJOHPGFBDIEBUBQPTJUJPO JOUIFSFTQPOTFQBDLFUUPFBDIIFBEFS fi FME %F fi OFUIFNBQQJOH %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 4VDDFTT
  137. WSProtocol.con fi gure("dRuby") do # … packet_type = druby_types[value_at(6)&.hex&.chr] if

    %w[true false].include?(packet_type) dissectors("dRuby Response") do sub("Success") do # … end sub(“Result") do # … end end else # … end end &BDIEBUBJOUIFSFTQPOTFQBDLFUJTEJTQMBZFE JOUIFJSPXOTVCUSFFT 4VDDFTT 8IFUIFSUIFNFUIPEDBMMXBTTVDDFTTGVMPSOPU  3FTVMU 3FUVSOWBMVF  %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 4VDDFTT
  138. sub(“Success") do items [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0

    }, { header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 6 }] end 5IJTJTBTVCUSFFGPSBOBMZ[JOH4VDDFTTEBUB  8IFUIFSUIFNFUIPEDBMMXBTTVDDFTTGVMPSOPU  %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 4VDDFTT
  139. sub(“Success") do items [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0

    }, { header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 6 }] end .BQQJOHGPSBOBMZ[JOHUIFTJ[FPGUIFEBUB )FBEFS fi FMEGPSUIFTJ[FPGEBUB 1PTJUJPOPGUIFTJ[FPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 4VDDFTT
  140. sub(“Success") do items [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset: 0

    }, { header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 6 }] end )FBEFS fi FMEGPSUIFUZQFPGEBUB 1PTJUJPOPGUIFUZQFPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 4VDDFTT .BQQJOHGPSBOBMZ[JOHUIFUZQFPGUIFEBUB
  141. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU 5IJTJTBTVCUSFFGPSBOBMZ[JOH3FTVMUEBUB  5IFSFUVSOWBMVFPGUIFNFUIPE
  142. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end )FBEFS fi FMEGPSUIFTJ[FPGEBUB 1PTJUJPOPGUIFTJ[FPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU .BQQJOHGPSBOBMZ[JOHUIFTJ[FPGUIFEBUB
  143. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end 8IBUUZQFPGEBUB  *OUFHFS 0SPUIFS %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU 5IFEBUBJOUIFUICZUFGSPNUIFCFHJOOJOHPG UIFQBDLFUNFBOTUIFUZQFPGUIBUEBUB
  144. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end *GUIFEBUBUZQFJT*OUFHFS %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  145. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end )FBEFS fi FMEGPSUIFUZQFPGEBUB 1PTJUJPOPGUIFUZQFPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU .BQQJOHGPSBOBMZ[JOHUIFUZQFPGUIFEBUB
  146. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end .BQQJOHGPSBOBMZ[JOHUIFJOUFHFSWBMVFPGUIFEBUB )FBEFS fi FMEGPSUIFWBMVFPGEBUB 1PTJUJPOPGUIFWBMVFPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  147. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end 4J[FPGUIFJOUFHFSWBMVF %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU 4JODFJOUFHFSWBMVFMFOHUIJTWBSJBCMF  JUNVTUTQFDJGZXIFSFUIFFOEPGUIFEBUBJT UPP
  148. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end def convert_form_to_int(n) n = n ^ 128 - 128 if n == 0 then 0 elsif n >= 4 then n - 5 elsif n < -6 then n + 5 # … end end 4JODFUIFWBMVFTBSFJO.BSTIBMGPSNBU JUOFFETUPCF DPOWFSUFEUPJOUFHFSSFQSFTFOUBUJPOCFGPSFEJTQMBZ %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  149. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end *GUIFEBUBUZQFJTOPUJOUFHFS %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  150. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end )FBEFS fi FMEGPSUIFUZQFPGEBUB 1PTJUJPOPGUIFUZQFPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU .BQQJOHGPSBOBMZ[JOHUIFUZQFPGUIFEBUB
  151. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end .BQQJOHGPSBOBMZ[JOHUIFTUSJOHWBMVFPGUIFEBUB )FBEFS fi FMEGPSUIFWBMVFPGEBUB 1PTJUJPOPGUIFWBMVFPGEBUB %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  152. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end 4JODFTUSJOHWBMVFMFOHUIJTBMTPWBSJBCMF  JUNVTUTQFDJGZXIFSFUIFFOEPGUIFEBUBJT 4J[FPGUIFTUSJOHWBMVF %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  153. sub(“Result") do result_tree_items = [{ header: :hf_druby_size, endian: WSDissector::ENC_BIG_ENDIAN, offset:

    7 }] result_value_size = value_at(7, :gint32, WSDissector::ENC_BIG_ENDIAN) result_value_type = druby_types[value_at(13).hex.chr] if result_value_type == “Integer" result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 13 }) result_tree_items.push({ header: :hf_druby_integer, value: convert_form_to_int(value_at(14)&.to_i), size: result_value_size.hex - 3, offset: 14}) else result_tree_items.push({ header: :hf_druby_type, endian: WSDissector::ENC_BIG_ENDIAN, offset: 14 }) result_tree_items.push({ header: :hf_druby_string, endian: WSDissector::ENC_NA, size: result_value_size.hex - 10, offset: 16 }) end items result_tree_items end end 5IJTDPNQMFUFTUIFEJTTFDUPSTFDUJPO GPSSFTQPOTFQBDLFUT %JTTFDUPSTFDUJPOGPSSFTQPOTFQBDLFUTBOBMZTJT 3FTVMU
  154. WSProtocol.con fi gure("dRuby") do # … packet_type = druby_types[value_at(6)&.hex&.chr] if

    %w[true false].include?(packet_type) # … else dissectors("dRuby Request") do sub(“Ref") do # … end sub(“Message") do # … end sub(“Args size") do # … end sub(“Args") do # … end sub(“Block”) do # … end end end 3FRVFTUQBDLFU 3FG .FTTBHF "SHVNFOUTTJ[F "SHVNFOUT #MPDL 3FRVFTUQBDLFUTBMTPSFRVJSF BNBQQJOHEF fi OJUJPOJOUIFEJTTFDUPSTFDUJPO %JTTFDUPSTFDUJPOGPSSFRVFTUQBDLFUTBOBMZTJT 3FTQPOTFQBDLFU
  155. /PX MFUTBOBMZ[FBE3VCZQBDLFU XJUIUIJTE3VCZEJTTFDUPS

  156. require “drb” class Foo def greeting(name) "Hello #{name}" end def

    sum(x, y) x + y end def with_block yield end end foo = Foo.new DRb.start_service(“druby://…”, foo) sleep require “drb” DRb.start_service foo = DRbObject.new_with_uri(“druby://…”, foo) p foo.greeting(“dRuby”) p foo.sum(1, 2) p foo.with_block { “with block” } )FSFBSFUIFE3VCZTDSJQUTUPSVO # A (sending response packets) # B (sending request packets)
  157. %FNP

  158. 4P *IPQFZPVFOKPZ EJTTFDUPSTEFWFMPQNFOUJO3VCZ XJUIFYUFOEFE8JSFTIBSL ɹa1MFBTFTFF3&"%.&UPHFUTUBSUFE ɹTIJPJNNXJSFTIBSL@XJUI@NSVCZ ɹIUUQTHJUIVCDPNTIJPJNNXJSFTIBSL@XJUI@NSVCZ

  159. 5IBOLZPVGPSZPVSBUUFOUJPO *OTQJSFEGSPN !N@TFLJ !VE[VSB 4QFDJBMUIBOLTUP !PLVSBNBTBGVNJ 5IF8JSFTIBSLDPNNVOJUZ

  160. 'PSXIFOUIFEFNPEPFTOUXPSL

  161. &YFDVUFUIFE3VCZTDSJQUT

  162. $BQUVSFUIFE3VCZQBDLFUT

  163. $BQUVSFUIFE3VCZQBDLFUT /PB3FRVFTUQBDLFU $BMM'PPHSFFUJOHGSPN"UP#  /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPHSFFUJOHGSPN#UP"  /PB3FRVFTUQBDLFU $BMM'PPTVNGSPN"UP# 

    /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPTVNGSPN#UP"  /PB3FRVFTUQBDLFU $BMM'PPXJUI@CMPDLGSPN"UP#  /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPXJUI@CMPDLGSPN#UP"
  164. E3VCZQBDLFUTPG'PPHSFFUJOH /PB3FRVFTUQBDLFU $BMM'PPHSFFUJOHGSPN"UP# /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPHSFFUJOHGSPN#UP"

  165. E3VCZQBDLFUTPG'PPTVN /PB3FRVFTUQBDLFU $BMM'PPTVNGSPN"UP# /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPTVNGSPN#UP"

  166. E3VCZQBDLFUTPG'PPXJUI@CMPDL /PB3FRVFTUQBDLFU $BMM'PPXJUI@CMPDLGSPN"UP# /PB3FTQPOTFQBDLFU 3FUVSOWBMVFPG'PPXJUI@CMPDLGSPN#UP"