ãããã£ãŠãWiresharkã§ã解ååŠçããã©ã°ã€ã³ãäœæããçµéšãã»ãšãã©ãªãã£ããããç¥èãšçµéšãã³ãã¥ããã£ãšå ±æããããšã«ããŸããã å°æ¥å¿ èŠã«ãªãå Žåã«åããŠãèªåã§æžããŠãã ããã
解å -緯床 解åã解åããã解å
泚1ïŒèšäºãæžããšããèªè ã¯WiresharkãŠãŒãã£ãªãã£ã«ç²ŸéããŠããããã®åºæ¬æ©èœã®äœ¿çšæ¹æ³ãç¥ã£ãŠãããšæ³å®ããŸããã
泚2ïŒç§ã¯Linuxã§äœæ¥ããŠããããããã®OSçšã®ãã©ã°ã€ã³ãäœæããŸããã Windowsã§ã¯ããã©ã°ã€ã³ãã³ã³ãã€ã«ããå¿ èŠããããŸãã éãã¯ãã¡ã€ã¯ãã¡ã€ã«ã«ã®ã¿ãããšæããŸãã
泚3ïŒç§ãåãçµãã§ãããããã³ã«ã¯ãç¬èªã®ãããã³ã«ã§ããã100äžä»¶ã®ç§å¯ä¿æå¥çŽã®ããããã®èšäºã§ã¯ç¬èªã®ãããã³ã«ãæ€èšããŠããŸãã
Fooãããã³ã«
äžèšã§èšãã°ãç§ã¯çºæããããããã³ã«ã説æããŸãã ãã®ãããã³ã«ãUDPãããã³ã«ã®äžã«çœ®ãã次ã®æ§é ã«ããŸãããã
- 1ãã€ã-ãããã³ã«ããŒãžã§ã³
- 1ãã€ã-ãã±ããã¿ã€ã
- 1ãã€ã-ããããçš®é¡ã®ãã©ã°
- 1ãã€ã-äœããã®ããŒã«å€æ°
- 4ãã€ã-ãã€ããŒãé·
- 0ã200ãã€ã-ãã€ããŒã
ç°å¢èšå®
ãã©ã°ã€ã³ã®äœæãéå§ããåã«ãäœããé 眮ããäœæããã©ããã§å€æŽããå¿ èŠããããŸãã Wiresharkãã€ã³ã¹ããŒã«ãèŠæ±ãããã®ã¯æ¬¡ã®ãšããã§ãã
- pythonïŒ2çªç®ã®ããŒãžã§ã³ã ãšæããŸããã3çªç®ã®ããŒãžã§ã³ã§ã¯ãããŸããïŒ
- ã·ãã±
- ãã€ãœã³
- ãã¬ãã¯ã¹
å¿ èŠãªãã®ããã¹ãŠã€ã³ã¹ããŒã«ãããããã©ã°ã€ã³ãäœæããããŒãžã§ã³ã®WiresharkãœãŒã¹ã³ãŒããããŠã³ããŒãããŸãã ç§ã®å Žåãå®å®ãã©ã³ã1.6ã®ãœãŒã¹ïŒ
$ cd $HOME $ svn co http://buildbot.wireshark.org/trunk-1.6/ wireshark
ã³ã³ãã€ã«ãæ©èœããŠããããšãããã³å¿ èŠãªãã¹ãŠã®ãŠãŒãã£ãªãã£ãšã©ã€ãã©ãªãã€ã³ã¹ããŒã«ãããŠããããšã確èªããã«ã¯ã次ãå®è¡ããŸãã
$ cd wireshark $ ./autogen.sh $ ./configure
ãã¹ãŠãæ£åžžãªå Žåã¯ããã©ã°ã€ã³ãã©ã«ããŒã«ç§»åããããã«ãããã³ã«åãæã€ç¬èªã®ãã©ã«ããŒãäœæããŸãã
$ cd $HOME/wireshark/plugins $ mkdir foo $ cd foo $ touch packet-foo.c
ãã¬ãŒã
ããã§ã¯ããã®äž»èŠéšåã§ãããã©ã°ã€ã³ãã¬ãŒã ã¯ãŒã¯ã匷調衚瀺ããããšããå§ããããšæããŸããããã¯ãWiresharkããã©ã°ã€ã³ããããã¯ã¢ãããããã®ã«ååã§ãã
packet-foo.c
#ifdef HAVE_CONFIG_H # include "config.h" #endif #include <epan/packet.h> #define FOO_PORT 35000 /* UDP , FOO . */ static int proto_foo = -1; /* . */ void proto_register_foo(void) { proto_foo = proto_register_protocol ( "FOO Protocol", /* */ "FOO", /* */ "foo" /* */ ); }
æåã«ã proto_register_protocolïŒïŒé¢æ°ãåŒã³åºããŸãããã®é¢æ°ã¯ãããã³ã«ãç»é²ããäžæã®èå¥åãè¿ããŸãã ããã°ã©ã ã®ããŸããŸãªéšåã«è¡šç€ºããããããã³ã«ã®3ã€ã®ç°ãªãååã«é¢æ°ã転éããŸãã ïŒããšãã°ããsharkãèšå®ã§ã¯ãFOO Protocolãããã³ãFOOããšããååã䜿çšããããã£ã«ã¿ãŒãã£ãŒã«ãã§ã¯ãfooããšããç¥èªã䜿çšãããŸããïŒ
次ã«ããã£ãããããfooããã±ãŒãžã解èªããããã«å¿ èŠãªå Žåã«åŒã³åºãããé¢æ°ãå²ãåœãŠãå¿ èŠããããŸãã ããã¯ã create_dissector_handleïŒïŒé¢æ°ãåŒã³åºãããšã«ãã£ãŠè¡ãããŸãã
void proto_reg_handoff_foo(void) { static dissector_handle_t foo_handle; foo_handle = create_dissector_handle(dissect_foo, proto_foo); dissector_add_uint("udp.port", FOO_PORT, foo_handle); }
ããã§ã¯ãæ§æã«é¢ããŠãããã³ã«ãå解ãã proto_fooãããã³ã«ã«ãã€ã³ããããšããæ±ãäœæ¥ãè¡ããã£ã»ã¯ã¿ãã³ãã©ãç»é²ããŸãã 次ã«ããã³ãã©ãŒãããã©ãã£ãã¯ãé²ããšäºæ³ãããUDPããŒãã«é¢é£ä»ããŸãã ãããã£ãŠãWiresharkã¯ãåœç€Ÿãæå®ããããŒãïŒ35000ïŒã§äœããã®ã¢ã¯ãã£ããã£ãçºçãããšãusããåŒã³åºããŸãã
é¢æ°proto_register_fooïŒïŒããã³proto_reg_handoff_fooïŒïŒããœãŒã¹ãã¡ã€ã«ã®æåŸã«èšè¿°ããå¿ èŠããããšããåæããããŸãã
çŸåšãæãéèŠãªããšã¯ããã£ã»ã¯ã¿ã³ãŒãèªäœãèšè¿°ããããšã§ãã
static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO"); col_clear(pinfo->cinfo, COL_INFO); }
ãã®é¢æ°ã¯ã詳现ã«æž¡ãããããã±ãŒãžã§æ©èœããããã«åŒã³åºãããŸãã ãã±ããããŒã¿ã¯ç¹å¥ãªãããã¡tvbã«ä¿åãããŸãã pinfoã«ã¯ ããããã³ã«ã«é¢ããäžè¬æ å ±ãå ¥ããŸãã ãŸãã ããªãŒã§ã¯ãWiresharkã®åºåã§ãããã³ã«ã®æçµã¿ã€ãã決å®ããããšãäž»ãªå€æŽãçºçããŸãã
æåã®è¡ã§ã¯ã[ ãããã³ã« ]åã«å€ãèšå®ããŸãã 2çªç®ã§ã¯ã[ æ å ± ]åãã¯ãªã¢ããŸãã ïŒéåžžãäž¡æ¹ã®åã¯ãã±ãããã£ããã£äžã«è¡šç€ºãããŸããïŒ
çŸåšããã©ã°ã€ã³ãå®å šã«ãã«ãããŠWiresharkã«ã¢ããããŒãã§ããããã«ãçŸæç¹ã§ã¯æå°éã®ã³ãŒãããããŸãã
ãã©ã°ã€ã³ã¢ã»ã³ããª
ïŒLinuxçšã«ïŒãã«ãããã«ã¯ããã£ã¬ã¯ããªMakefile.amãMakefile.commonãmoduleinfo.hã«ããã€ãã®ãã¡ã€ã«ãååŸããå¿ èŠããããŸãã
- Makefile.am-UNIX / Linux makeãã¡ã€ã«
- Makefile.common-UNIX / Linuxããã³Windowsçšã®æ±çšã¡ã€ã¯ãã¡ã€ã«ããã©ã°ã€ã³ãã¡ã€ã«åãå«ãŸããŠããŸã
- Makefile.nmake-Windowsçšã®ã¡ã€ã¯ãã¡ã€ã«
- moduleinfo.h-ãã©ã°ã€ã³ã®ããŒãžã§ã³ãå«ãŸããŠããŸã
- moduleinfo.nmake-Windowsçšã®DLLã®ããŒãžã§ã³æ å ±ãå«ãŸããŠããŸã
- packet-foo.c-ãã£ã»ã¯ã¿ã®ãœãŒã¹ã³ãŒã
set(DISSECTOR_SRC packet-foo.c ) set(PLUGIN_FILES plugin.c ${DISSECTOR_SRC} ) set(CLEAN_FILES ${PLUGIN_FILES} ) if (WERROR) set_source_files_properties( ${CLEAN_FILES} PROPERTIES COMPILE_FLAGS -Werror ) endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) register_dissector_files(plugin.c plugin ${DISSECTOR_SRC} ) add_library(foo ${LINK_MODE_MODULE} ${PLUGIN_FILES} ) set_target_properties(foo PROPERTIES PREFIX "") set_target_properties(foo PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") target_link_libraries(foo epan) install(TARGETS foo LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} NAMELINK_SKIP RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} )
æ³šïŒ CMakeLists.txtãã¡ã€ã«ãã©ã®ããã«èŠããããæ¯åæãåºãããšã¯ã§ããŸããããããšãã°ãã€ã³ã¿ãŒãªã³ã¯ãªã©ã®æ¢åã®ãã©ã°ã€ã³ã®ãã©ã«ããŒããã³ããŒããŸãã ãããŠããã®ãã¡ã€ã«å ã®ã€ã³ã¿ãŒãªã³ã¯ãžã®ãã¹ãŠã®åç §ãfooã«çœ®ãæããŸãã
次ã«ãã¢ã»ã³ããªããã»ã¹ãèªååããããã®ãã©ã°ã€ã³ããŒã«ã«ã€ããŠãç¥ãããã ããã
$ cd $HOME/wireshark/ $ vim CMakeLists.txt
ã€ã³ãã³ããæå®ãããè¡ãplugins / fooããè¿œå ããŸãã
....... if(ENABLE_PLUGINS) set(HAVE_PLUGINS 1) set(PLUGIN_DIR="${DATAFILE_DIR}/plugins/${CPACK_PACKAGE_VERSION}") set(PLUGIN_SRC_DIRS plugins/foo plugins/asn1 plugins/docsis .......
ããã§ãã³ã³ãã€ã«ããã³ãªã³ã¯äžã«äœæããããã¡ã€ã«ãä¿åããããã£ã¬ã¯ããªãäœæããŸãã 次ã«ãã¢ã»ã³ããªããã»ã¹èªäœãå®è¡ããŸãã 次ã®æé ã¯ã $ HOME / wireshark /ãã£ã¬ã¯ããªããå®è¡ãããŸã
$ mkdir build $ cd build $ cmake .. $ make foo
ã³ã³ãã€ã«ã«æåãããšã foo.soã©ã€ãã©ãªã$ HOME / wireshark / build / lib /ãã©ã«ãã«ååŸããŸãã
è©Šé転
ãã¡ã€ã«foo.soã/usr/lib/wireshark/plugins/1.6.0/ãã£ã¬ã¯ããªã«ã³ããŒããWiresharkãå®è¡ããŸãã [ãã«ã-> Wiresharkã«ã€ããŠ]ã«ç§»åãã[ ãã©ã°ã€ã³ ]ã¿ãã«ç§»åããŠã衚瀺ããããªã¹ãã§ãã©ã°ã€ã³foo.soãèŠã€ããŸãã
ãã©ã°ã€ã³ããããã³ã«ãèªèããããšã確èªããããã«ããã±ãããã£ããã£ãéå§ãããããã¯ãŒã¯ãä»ããŠãããã³ã«ã䜿çšããŠãã±ãããéä¿¡ããŸãã ïŒäŸãšããŠãUDPãããã¯ãŒã¯ãä»ããŠFOOãããã³ã«ãã±ãããéä¿¡ããããã°ã©ã ãäœæããŸããããã®ã³ãŒãã¯èšäºã®æåŸã«ãããŸã ãïŒ
ã¯ãŒãã³ã°ãã£ã»ã¯ã¿ãŒ
ãã©ã°ã€ã³ãã¬ãŒã ã¯ãŒã¯ãçšæã§ããã®ã§ããŸã äœã®åœ¹ã«ãç«ã¡ãŸããããå°ãªããšãèµ·åãããããããã³ã«ããæžã蟌ã¿ããŸãã ã§ããæãç°¡åãªããšã¯ããããã³ã«ã®å¢çãå®çŸ©ããããšã§ãã
ãããè¡ãã«ã¯ããŸããããªãŒïŒ tree ïŒã«ãã©ã³ããäœæããããã«ãã³ãŒãçµæãé 眮ããŸãã ãã£ã»ã¯ã¿ã¯ã2ã€ã®ç°ãªãã±ãŒã¹ã§åŒã³åºãããŸãã1ã€ã¯ããã±ãŒãžã«é¢ããæŠèŠæ å ±ãååŸããå¿ èŠãããå Žåããã1ã€ã¯åãããã±ãŒãžã«é¢ãã詳现æ å ±ã衚瀺ããå¿ èŠãããå Žåã§ãã ããªãŒãžã®ãã€ã³ã¿ãŒãNULLã®å ŽåããµããªãŒæ å ±ã®ã¿ãèŠæ±ãããŸãã ãã以å€ã®å ŽåãWiresharkãŠãŒã¶ãŒã«è¡šç€ºããã詳现æ å ±ãããªãŒã«è¿œå ããããæ±ããããŸãã ããã念é ã«çœ®ããŠããã£ã»ã¯ã¿ã¯æ¬¡ã®åœ¢åŒãåããŸãã
static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *ti = NULL; ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, FALSE); } }
ããã§ã proto_tree_add_itemïŒïŒãåŒã³åºããŠããªãŒã«ãã©ã³ããè¿œå ããŸããã ãã®ã¹ã¬ããã«ã¯ã fooãããã³ã«ã«é¢ãããã¹ãŠã®è©³çŽ°ãå«ãŸããŸãã ãŸãããããã³ã«ã䜿çšãããã±ããã®ããŒã¿é åãããŒã¯ããŸãã ç§ãã¡ã®å Žåãããã¯UDPãã±ããã®ããŒã¿ãè¶ ããé åå šäœã§ããããã¯ããããã³ã«ã«å¥ã®ãããã³ã«ãå«ãŸããå Žåãèæ ®ããªãããã§ãã
proto_tree_add_itemïŒïŒé¢æ°ã®ãã©ã¡ãŒã¿ãŒïŒ
- tree-ããã±ãŒãžã«é¢ããæ å ±ã®ããªãŒå šäœ
- proto_foo-ãããã³ã«ã®èå¥å
- tvb-ããŒã¿ãããã¯ïŒãããã³ã«ã«ãã£ãŠéä¿¡ãããããŒã¿ïŒ
- 0 - tvbãããã¯å ã®ããŒã¿ãã©ã®äœçœ®ããfooãããã³ã«ã®ããŒã¿ã§ãããã瀺ããŸã
- -1-ãããã³ã«ãå æãããã€ãæ°ïŒã-1ãã¯ãããŒã¿ãããã¯ã®çµãããŸã§ããæå³ããïŒ
- FALSE-ãã€ãé ã瀺ããŸã ïŒTRUE-ãã€ãããããã¯ãŒã¯é ã«é 眮ãããŠããå ŽåïŒã
次ã®ã¹ãããã¯ã詳现ãè¿œå ããããšã§ãã ãã®ã¹ãããã§ã¯ã埩å·åã«åœ¹ç«ã€ããã€ãã®é åãšè¿œå ã®é¢æ°åŒã³åºããäœæããå¿ èŠããããŸãã å€æŽã¯ãåã«ç€ºããproto_register_fooïŒïŒé¢æ°ã®æ¬äœã«åœ±é¿ããŸãã
proto_register_fooïŒïŒã®å é ã«2ã€ã®éçé åãè¿œå ããŸãã 次ã«ã proto_register_protocolïŒïŒé¢æ°ãåŒã³åºããåŸã«ãããã®é åãç»é²ããŸãã
void proto_register_foo(void) { static hf_register_info hf[] = { { &hf_foo_hdr_version, { "FOO Header Version", "foo.hdr.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_foo_hdr_type, { "FOO Header Type", "foo.hdr.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } } }; static gint *ett[] = { &ett_foo }; proto_foo = proto_register_protocol ( "FOO Protocol", "FOO", "foo" ); proto_register_field_array(proto_foo, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); }
ãããŠãã°ããŒãã«å€æ°proto_fooã®å®£èšã®çŽåŸã«ãããã«3ã€ã®å®£èšãè¿œå ããŸãã
static gint ett_foo = -1; static int hf_foo_hdr_version = -1; static int hf_foo_hdr_type = -1;
次ã«ããããã³ã«ã®è¡šç€ºãæ¹åããŸãã
if (tree) { proto_item *ti = NULL; proto_tree *foo_tree = NULL; ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, FALSE); foo_tree = proto_item_add_subtree(ti, ett_foo); proto_tree_add_item(foo_tree, hf_foo_hdr_version, tvb, 0, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_hdr_type, tvb, 1, 1, FALSE); }
ãããã³ã«ã«é¢ããWiresharkã®ç¥èã¯ãçŸåšããã«è©³çŽ°ã«ãªã£ãŠããŸãã ãããŸã§ã®ãšãããfooãããã³ã«ã®æåã®2ãã€ãã®ã¿ãèªèããŠããããããã¯ãããããããã³ã«ããŒãžã§ã³ãšãã±ããã¿ã€ããæ åœããŠããŸãã
proto_item_add_subtreeïŒïŒé¢æ°ã®åŒã³åºãã¯ãå°çãããã±ããå šäœã«é¢ããæ å ±ã®ããªãŒã«ãfooãããã³ã«ã«é¢ãã詳现ãå«ãè¿œå ã®ãã©ã³ãïŒ foo_tree ïŒãè¿œå ããŸããã foo_treeã§ã¯ ããããã³ã«ã詳现ã«èª¬æããŸãã
ett_fooå€æ°ã¯ãWiresharkããã°ã©ã ã®åºåã®ãããã³ã«æ å ±ããªãŒã®ãæ¡åŒµããå¶åŸ¡ããŸãã ãã®å€æ°ã¯ããã±ããã移åãããšãã«ãããã³ã«ãå±éããå¿ èŠããããã©ãããèšæ¶ããŸãã
proto_tree_add_itemïŒïŒã¯ ãä»åã¯hf_foo_hdr_versionå€æ°ã䜿çšããŠãç®çã®åœ¢åŒã§å€ãåºåããŸãã hdr_version-äœçœ®0ããå§ãŸãtvbããã®1ãã€ããhdr_type-äœçœ®1ããå§ãŸãtvbããã®1ãã€ã
éçé åã®hf_foo_hdr_version宣èšãèŠããšã詳现ãªãã£ãŒã«ãã衚瀺ãããŸãã
- hf_foo_hdr_version-ãã©ã³ãã€ã³ããã¯ã¹
- FOOããããŒããŒãžã§ã³ -ãã£ãŒã«ãã®åœå
- foo.hdr.versionã¯ããã±ãŒãžã®ãã£ã«ã¿ãªã³ã°ã«äœ¿çšãããè¡ã§ãïŒãã®ã¿ã€ãã®è¡ã¯ãã£ã«ã¿ãŒãã£ãŒã«ãã«ãããŸãïŒ
- FT_UNIT8 - tvbããŒã¿ãããã¯ããèªã¿åãèŠçŽ ã®ã¿ã€ããšãµã€ãºã瀺ããŸã ã ãã®å Žåãããããã³ã«ããŒãžã§ã³ããã£ãŒã«ãã笊å·ãªãæŽæ°åã®1ãã€ãã§ããããšã瀺ããŸãã ïŒä»ã®å¯èœãªã¿ã€ãã¯ã wireshark / epan / ftypes / ftypes.hã«ãããŸã ïŒ
- BASE_DEC-æ°å€åã®å Žåãæ°å€ãåºåããã·ã¹ãã ã瀺ããŸãã ïŒBASE_HEXãŸãã¯BASE_OCTã«ããããšãã§ããŸããéæ°å€åã®å Žåã¯ãBASE_NONEã䜿çšããŸããïŒ
ããã§ããã©ã°ã€ã³ãå床ãã«ãããWiresharkãšäžç·ã«å®è¡ã§ããŸãã Wiresharkã®åºåãããé©åã«ãªã£ãããšãããããŸãã
ããŠãfooãããã³ã«ã®ãã³ãŒãã«é¢ããäœæ¥ãçµäºããŸãããã ãããè¡ãã«ã¯ãããã«ããã€ãã®ã°ããŒãã«å€æ°ã宣èšããããã€ãã®è¿œå ã®åŒã³åºããè¡ãå¿ èŠããããŸãã
... static int hf_foo_hdr_flags = -1; static int hf_foo_hdr_bool = -1; static int hf_foo_pl_len = -1; static int hf_foo_payload = -1; ... void proto_register_foo(void) { ... { &hf_foo_hdr_flags, { "FOO Header Flags", "foo.hdr.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_foo_hdr_bool, { "FOO Header Boolean", "foo.hdr.bool", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_foo_pl_len, { "FOO Payload Length", "foo.pl_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_foo_payload, { "FOO Payload", "foo.payload", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } } ... } static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { ... if (tree) { gint offset = 0; proto_item *ti = NULL; proto_tree *foo_tree = NULL; ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, FALSE); foo_tree = proto_item_add_subtree(ti, ett_foo); proto_tree_add_item(foo_tree, hf_foo_hdr_version, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_hdr_type, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_hdr_flags, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_hdr_bool, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_pl_len, tvb, offset, 4, TRUE); offset += 4; proto_tree_add_item(foo_tree, hf_foo_payload, tvb, offset, -1, FALSE); } }
ãããã£ãŠãçºæãããããã³ã«ã®ãã¹ãŠã®ãããã解èªããŸããã
埩å·åäžã«äœ¿çšããããŸããŸãªã¿ã€ãã®èŠçŽ ãFT_BOOLEANãFT_STRINGãããã³FT_UINT8ã確èªã§ããŸãã ãŸããéæ°å€èŠçŽ ã®å Žåã¯ãBASE_NONEã䜿çšãããŸããã
ããã§ãWiresharkã¯ãããã³ã«ã«ã€ããŠããªãè¯ãèããæã£ãŠããŸãã ãããŠããã®ã¹ãããã§ãã®ãããªè©³çŽ°ãåžžã«ååã§ããã°åæ¢ããããšãã§ããŸãã ãã©ã°ãã£ãŒã«ãã¯ãŸã ããããããåäœã§æåã§å±éããå¿ èŠããããŸãã ãŸãããããã³ã«ã®ããŒãžã§ã³ãäžæãªå Žåãçµè«ãä¿¡é Œããããšã¯å¯èœã§ããïŒ ãŸãããããŠæãéèŠãªãã€ã³ã- ãã€ããŒããã£ãŒã«ããªãã§pl_lenå€ããŒãã§ãã±ãããå°çããå Žåããã£ã»ã¯ã¿ã¯äŸå€ãã¹ããŒããŸã ã ãã®ããããã©ã°ã€ã³ãæ¹åããå ŽæããããŸãã ç¶ããŸããã...
åºåã«ããŒããè¿œå ãã
å®ç§ã«å¶éã¯ãããŸããïŒ ç§ãã¡ã®å Žåã§ãã ãŸããå°çããããã±ãŒãžã®ããŒãžã§ã³ãšã¿ã€ãã«ååãä»ããããšããå§ããŸããããããã«ãããããã±ãŒãžã衚瀺ãããšãã«æ å ±ãã¯ããã«éãèªèã§ããããã«ãªããŸãã ãããè¡ãã«ã¯ã2ã€ã®é åãå¿ èŠã§ãã
static const value_string packetversions[] = { { 1, "Version 1" }, { 0, NULL } }; static const value_string packettypes[] = { { 1, "Ping request" }, { 2, "Ping acknowledgment" }, { 3, "Print payload" }, { 0, NULL } };
é åã®äŸåé¢ä¿ã¯éåžžã«åçŽã§ã-ãå€ãå€ã®ååãã ãããã£ãŠãããã±ãŒãžã衚瀺ãããšããããã±ãŒãžã®åçªå·ã¯è¡šç€ºãããããã®æå³ãèŠããŠããŸããããããã«åã®èª¬æã衚瀺ãããŸãã ãããã®é åã«ã¢ã¯ã»ã¹ããã«ã¯ãWiresharkèªèº«ãæäŸããVALSãã¯ãã䜿çšããŸãã
{ &hf_foo_hdr_version, { "FOO Header Version", "foo.hdr.version", FT_UINT8, BASE_DEC, VALS(packetversions), 0x0, NULL, HFILL } }, { &hf_foo_hdr_type, { "FOO Header Type", "foo.hdr.type", FT_UINT8, BASE_DEC, VALS(packettypes), 0x0, NULL, HFILL } }
ããã±ãŒãžã®ããŒãžã§ã³ãšã¿ã€ãã決å®ããŸããã 次ã«ããã©ã°ã«ã€ããŠè©³ãã説æããŸãã
#define FOO_FIRST_FLAG 0x01 #define FOO_SECOND_FLAG 0x02 #define FOO_ONEMORE_FLAG 0x04 static int hf_foo_flags_first = -1; static int hf_foo_flags_second = -1; static int hf_foo_flags_onemore = -1; void proto_register_foo(void) { ... { &hf_foo_flags_first, { "FOO first flag", "foo.hdr.flags.first", FT_BOOLEAN, FT_INT8, NULL, FOO_FIRST_FLAG, NULL, HFILL } }, { &hf_foo_flags_second, { "FOO second flag", "foo.hdr.flags.second", FT_BOOLEAN, FT_INT8, NULL, FOO_SECOND_FLAG, NULL, HFILL } }, { &hf_foo_flags_onemore, { "FOO onemore flag", "foo.hdr.flags.onemore", FT_BOOLEAN, FT_INT8, NULL, FOO_ONEMORE_FLAG, NULL, HFILL } } ... } static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { ... proto_tree_add_item(foo_tree, hf_foo_hdr_flags, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_first, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_second, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_onemore, tvb, offset, 1, FALSE); offset += 1; ... }
ãã©ã°ã¯å€ãã1ããŸãã¯ã0ãã®1ãããã®æ å ±ã§ãããããã¿ã€ãFT_BOOLEANã䜿çšããŸãã ãŸãã6çªç®ã®ãã©ã¡ãŒã¿ãŒïŒFOO_FIRST_FLAGãFOO_SECOND_FLAGãFOO_ONEMORE_FLAGïŒã䜿çšããŠåãã©ã°ã®ãã¹ã¯ãèšå®ãããã€ãã®ã©ã®ãããã解éãããã決å®ããŸãã ãã¹ãŠã®ãã©ã°ã«åããªãã»ããå€æ°ã䜿çšããŠããããšã«æ³šæããŠãã ããã
çµè«ã¯ãã¯ããã«èªã¿ããããªããŸããã ããããåæ¢ããããšã¯ãªããããã«æçãªãã®ã«ããŸãã 泚ïŒWiresharkã§ã¯ãããã±ãŒãžããFOOãããã³ã«ããšåŒã³ãŸãã ãããã³ã«ã®ç»é²æã«ãã®ååãèšå®ããŸãã Wiresharkã¯ããã®ååã«è¿œå æ å ±ãè¿œå ããæ©èœãæäŸããŸãã ãã®ãã£ãŒã«ãã«ã¯ããããã³ã«ã®ã¿ã€ãã«é¢ããæ å ±ã衚瀺ãããŸãã ãããè¡ãã«ã¯ã tvb_get_guint8ïŒïŒ 2ã䜿çšããŠåã®å€ãååŸããå¿ èŠããããŸãã çµæã®å€ã¯ããããã³ã«åã®çŽåŸãš[ æ å ± ]åã®2ã€ã®å Žæã«è¡šç€ºãããŸãã
static void dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 packet_version = tvb_get_guint8(tvb, 0); guint8 packet_type = tvb_get_guint8(tvb, 1); guint32 packet_pl_len = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { gint offset = 0; proto_item *ti = NULL; proto_tree *foo_tree = NULL; ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, FALSE); foo_tree = proto_item_add_subtree(ti, ett_foo); proto_tree_add_item(foo_tree, hf_foo_hdr_version, tvb, offset, 1, FALSE); offset += 1; switch ( packet_version ) { case 1: col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s", val_to_str(packet_type, packettypes, "Unknown (0x%02x)")); proto_item_append_text(ti, ", Type: %s", val_to_str(packet_type, packettypes, "Unknown (0x%02x)")); proto_tree_add_item(foo_tree, hf_foo_hdr_type, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_hdr_flags, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_first, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_second, tvb, offset, 1, FALSE); proto_tree_add_item(foo_tree, hf_foo_flags_onemore, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_hdr_bool, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(foo_tree, hf_foo_pl_len, tvb, offset, 4, TRUE); packet_pl_len = tvb_get_ntohl(tvb, offset); offset += 4; if ( packet_pl_len ) proto_tree_add_item(foo_tree, hf_foo_payload, tvb, offset, -1, FALSE); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown version of Foo protocol (0x%02x)", packet_version); } } }
ååŸããå€ããã¯ãval_to_strïŒïŒã«æž¡ããæž¡ãããå€ã®èª¬ææååããŸãã¯èª¬æãèŠã€ãããªãå Žåã¯æå®ããæååãè¿ããŸãã
ãŸããäŸå€ãã¹ããŒãããå Žåã®äžé©åãªãã€ããŒãåŠçã«é¢ãããšã©ãŒãä¿®æ£ããŸããã
ããã«ãç°ãªãããŒãžã§ã³ã®ãããã³ã«ã«åå²ãè¿œå ããŸããã
è¿œå
Fooãããã³ã«ã®ã¯ãŒãã³ã°ãã£ã»ã¯ã¿ã®äŸ
tvb_get_guint8ïŒïŒ
tvb_get_guint8ïŒïŒé¢æ°ã«å ããŠã wireshark / epan / tvbuff.hãšãããã¡ã€ã«ã«èª¬æãèšèŒãããŠãããã®ãããã€ããããŸããã¢ãŒã«ã€ã
äœæ¥çšãœãŒã¹ãã¡ã€ã«ã§ã¢ãŒã«ã€ãããŸãã å«ãŸãããã®ïŒ- packet-foo.c-ãã£ã»ã¯ã¿ãã©ã°ã€ã³ã®ãœãŒã¹ã³ãŒã
- CMakeLists.txt-ãã©ã°ã€ã³ã®cmakeãã¡ã€ã«
- send-foo-packet.c-fooãã±ãããéä¿¡ããããã°ã©ã ã®ãœãŒã¹ã³ãŒã
fooãã±ãããããŒã35000ã«éä¿¡ããããã°ã©ã ã®ãªã¹ã*
#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #define FOO_PORT 35000 #define BUFFER_SIZE 210 struct _message { unsigned char pck_version; // = argv[1] unsigned char pck_type; // = 1 | 3 unsigned char pck_flags; // = rand unsigned char pck_boolean; // = rand unsigned int pck_payload_len; // = strlen(argv[2]) }; int main(int argc, char ** argv) { if ( argc != 3 ) { printf("Usage: %s <version> <ping|\"text\">\n", argv[0]); return 1; } struct sockaddr_in cli_addr; int s, cli_len = sizeof(cli_addr); char buf[BUFFER_SIZE]; struct _message msg; msg.pck_version = atoi(argv[1]); msg.pck_payload_len = 0; unsigned int randomData = open("/dev/urandom", O_RDONLY); unsigned int myRandomInteger; read(randomData, &myRandomInteger, sizeof(myRandomInteger)); msg.pck_flags |= myRandomInteger%8; read(randomData, &myRandomInteger, sizeof(myRandomInteger)); msg.pck_boolean = myRandomInteger%2; close(randomData); if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 ) { perror("socket"); exit(1); } memset((char*)&cli_addr, 0, sizeof(cli_addr)); cli_addr.sin_family = AF_INET; cli_addr.sin_port = htons(FOO_PORT); cli_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); memset(buf, 0, BUFFER_SIZE); if ( ! strcmp(argv[2], "ping") ) { msg.pck_type = 1; } else { msg.pck_type = 3; msg.pck_payload_len = (strlen(argv[2])<200)?strlen(argv[2]):200; strncpy(buf+sizeof(struct _message), argv[2], (strlen(argv[2])<200)?strlen(argv[2]):199); } memcpy(buf, (char*)&msg, sizeof(struct _message)); if ( sendto(s, buf, sizeof(struct _message)+msg.pck_payload_len, 0, (struct sockaddr*)&cli_addr, cli_len) == -1 ) { perror("sendto"); exit(1); } exit(0); }
*æãè ããä¿è·ãããŠããªãããã°ã©ã