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

Packet analysis with mruby on Wireshark - dRuby...

Packet analysis with mruby on Wireshark - dRuby as example

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

Other Decks in Programming

Transcript

  1. '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
  2. #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
  3. "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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. #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
  20. #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
  21. 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
  22. #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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. /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
  30. 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 
  31. 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
  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 5IFOJOUIFSFHJTUFSTFDUJPOPGUIFCMPDL  3FHJTUFSTFDUJPO 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF
  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 5IFQSPUPDPMJOGPSNBUJPO  JODMVEJOHUIFMJTUPGIFBEFS fi FMET BSFTUPSFEJO JOTUBODFWBSJBCMFTPGUIF841SPUPDPMJOTUBODF 841SPUPDPMDPO fi HVSF JOUIFDPO fi H fi MF !USBOTQPSU !QPSU ! fi MUFS !IFBEFST !OBNF
  34. 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
  35. 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
  36. 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 
  37. 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
  38. 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 
  39. 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
  40. 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
  41. 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
  42. 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 
  43. 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
  44. 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 
  45. 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
  46. 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
  47. 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!! //
  48. 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!! //
  49. 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
  50. #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
  51. 'JOBMMZ BEEUPUIFFYUFOTJPODPEF XIBUUIFEJTTFDUPSEPXIFOUSB ff i DJTPDDVSSFE 8IFOBUSB ff i DPDDVSSFE

    UIFEJTTFDUPSBMXBZTDBMMT BDBMMCBDLGVODUJPO -FUTBEEUIFSFTUPGXIBUXFXJMMEPJOUIJTGVODUJPO 3FNBJOJOHJTTVFT The callback function
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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!! //
  63. 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
  64. 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
  65. 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
  66. 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 
  67. *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
  68. 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--
  69. 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--
  70. 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
  71. 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 
  72. 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 
  73. 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 
  74. 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 
  75. 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
  76. *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 
  77. 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
  78. module DRb # … class DRbMessage # … def send_reply(stream,

    succ, result) stream.write(dump(succ) + dump(result, !succ)) rescue # … end # … end # … end IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSMJCESCESCSC-- 5IFTUSVDUVSFPGE3VCZSFTQPOTFQBDLFU "SFTQPOTFQBDLFUDPOUBJOTLJOETPGEBUB
  79. 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 
  80. 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 
  81. 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
  82. 5ZQFPGEBUBJO.BSTIBMGPSNBUJTUPPEJ ff i DVMU      

    #VUBTJUJTOPX UIFWBMVFTJO UIJTVOSFBEBCMFGPSNBUJTEJTQMBZFEJOUIFl1BDLFU%FUBJMTzQBOF
  83. 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
  84. 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
  85. 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
  86. 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
  87. 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
  88. 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
  89. 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
  90. 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
  91. 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
  92. 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
  93. 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
  94. 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
  95. 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
  96. 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
  97. 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
  98. 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
  99. 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
  100. 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
  101. 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
  102. 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
  103. 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
  104. 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
  105. 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
  106. 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
  107. 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
  108. 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)
  109. $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"