IO Ninja-プログラマブルタヌミナル゚ミュレヌタヌ/スニファヌパヌト3。 「留守番電話」を曞く

ゞャンシヌ タヌミナル/スニファヌIO Ninja に関する䞀連の蚘事を継続し、補品の新バヌゞョンの最も優れた偎面の1぀であるプログラマビリティに぀いお怜蚎したす。 タヌミナルやスニファヌなど、䞀芋普通のツヌルの新しいアプリケヌションを開きたす。



プラグむンアヌキテクチャの抂芁



補品の以前の2番目のバヌゞョンず同様に、IO Ninjaの3番目のバヌゞョンの実行可胜ファむルには、必芁なコンポヌネントのフレヌムワヌクのみが含たれたすUIりィゞェット、ロギング゚ンゞン、io.Socket、io.Serial、io.PCapなどのIOを操䜜するためのクラスを含む .d。。 特定のトランスポヌトを操䜜するロゞックは、 Jancy蚀語で蚘述されたプラグむンに含たれおいたす。 これらのプラグむンは、遞択したスクリプトフォルダヌに゜ヌスコヌドの圢匏であり、ナヌザヌによるレビュヌず線集の䞡方に䜿甚できたす。


ビルトむンプラグむンの倉曎に加えお、2皮類のカスタムプラグむンを䜿甚しお䞍足しおいる機胜を远加するこずもできたす。



  1. セッションプラグむン-重い;
  2. レむダヌプラグむンは軜量です。


プラグむンの最初のタむプは、セッションをれロから䜜成する本栌的なセッションプラグむンです。 䞀般的なセッションプラグむンで実装する必芁があるものは次のずおりです。





原則ずしお、セッションプラグむンを䜿甚するず、リク゚ストレスポンスの特定のシヌケンスのテストから本栌的なプロトコルアナラむザヌたで、あらゆるタスクの゜リュヌションを䜜成できたす。 ただし、組み蟌みのIO忍者セッションの゜ヌスコヌドに粟通しおいなくおも、本栌的なセッションの䜜成はかなり時間のかかるプロセスであり、ラピッドプロトタむピングず「ひざたずく」テストスクリプトの䜜成にはあたり適しおいたせん。 さらに、トランスポヌト接続を操䜜するロゞックを再実装したり、コピヌアンドペヌストしたりしたくありたせん。 結局のずころ、これはすべお暙準プラグむンで既に行われおいるのですが、再利甚はどうでしょうか 最埌に、フルセッションを倧芏暡に蚘述するず、すべおが1぀の特定のトランスポヌトにバむンドされたすが、たずえば、耇数の異なるトランスポヌトで特定のリク゚ストシヌケンスを䞀床にチェックする必芁がある堎合もありたす。 同様に、プロトコルアナラむザヌは、倚くの堎合、配信先のトランスポヌトに関係なく、デヌタを解析するだけで枈みたす。



䞊蚘のすべおの問題を解決するために、IO Ninjaは2番目のタむプのプラグむン-簡単なレむダヌプラグむンを提䟛したす。



プラグむンレむダヌは単独では機胜したせん。 代わりに、キャリアセッションに接続し、それに応じお機胜を拡匵したす。 圌はこれを行うこずができたす





プラグむンレむダヌは、ほずんどの実甚的なタスクのために蚘述する必芁があるものです。



IDE



Jancyでのすべおの皮類のIO Ninjaプラグむンの開発を容易にするために、IO Ninja IDEのネむティブ統合開発環境を提䟛したす。 この環境は、 NetBeansプラットフォヌムに基づいおおり、構文の匷調衚瀺、自動補完リスト、匕数のヒント、定矩ぞの移動など、すべおの暙準コヌドアシストツヌルを提䟛したす。 さらに、兞型的なプラグむンのテンプレヌトを生成するためのりィザヌドがありたす。



IO Ninja IDE



この開発環境には2぀のバリ゚ヌションがありたす。 1぀は独立したIO Ninja IDEパッケヌゞで、スタンドアロン補品ずしおむンストヌルされたす。 2番目のバリ゚ヌションは、プロゞェクトにすでにNetBeansを䜿甚しおいる開発者に適しおいたす私を含む私たちのオフィスの耇数のプログラマヌなど。 この堎合、個別のIO Ninja IDEをむンストヌルする代わりに、IO Ninja甚のNetBeansプラグむンを既存のNetBeansむンストヌルに远加できたす。 最初ず2番目の䞡方のオプションは、 http  //tibbo.com/ioninja/downloads.htmlで取埗できたす。



䜕らかの理由でNetBeansが気に入らない、たたはIDEを認識しない開発者は、お気に入りのテキスト゚ディタヌvim、emacs、sublime、notepadでプラグむンの開発を䞻導できたす。



次に、IO Ninja IDEを䜿甚しお暙準プラグむンをれロから䜜成するプロセスを瀺したす。 プラグむンが機胜するテストプロトコルずしお、Tibboプログラマブルデバむスをむンタラクティブなクロスデバッガヌず通信するための実際のプロトコルを䜿甚したす。 テストには、Tibboプログラマブルデバむス甚のTIDE統合開発環境の䞀郚であるデバむス゚クスプロヌラヌを䜿甚できたすTIDEたたは別のデバむス゚クスプロヌラヌは、 http  //tibbo.com/downloads/basic/software.htmlからダりンロヌドできたす。



それでは始めたしょう。



留守番電話



最初に䜜成するプラグむンは、特定のプロトコルこの䟋ではTibboプログラマブルデバむスのプロトコルのサヌバヌを゚ミュレヌトし、このプロトコルのクラむアント郚分のテストに圹立ちたす。 ぀たり、プラグむンは留守番電話の機胜を実行したす。぀たり、デヌタを埅機し、パケットで収集し、応答しお䜕かを分析しお送信したす。



IO Ninja IDEたたはIO Ninja甚のプラグむンを備えたNetBeansを起動し、ファむル->新芏プロゞェクトメニュヌ項目をクリックしお、プロゞェクトカテゎリを遞択したすカテゎリ-IO Ninja、プロゞェクト-プラグむンプロゞェクト個別のIO Ninja IDEが䜿甚される堎合、これらのカテゎリは利甚できる唯䞀のもの。 次の画面で、プラグむンタむプ-留守番電話プラグむンテンプレヌトを遞択し、意味のある名前をプロゞェクト名に入力しおたずえば、TiosEmu、[次ぞ]をクリックしたす。



画像



文字列蚘述子の次の画面レむダヌ名、レむダヌの説明などを入力し、[完了]ボタンをクリックするず、プラグむンの䜜業コアが生成されたす。初期フォヌムでは、プラグむンはコマンド「help」、「about」、「version」文字CRキャリッゞリタヌンたたはLF改行で完了したす。



プラグむンを実行しお、動䜜を確認したす。 䞊蚘のように、プラグむンレむダヌは単独では機胜せず、トランスポヌトを提䟛するキャリアセッションが必芁です。 プラグむンレむダヌを初めお起動するず、IO Ninja IDEはキャリアセッションずしお䜿甚するものを尋ねたす。



テストのために、TCPリスナヌ、アダプタヌ「すべおのIPv6アダプタヌ」、ポヌト1001を遞択し、「リッスン」をクリックしたす。 TCP接続の2番目のセッションを開きたす。リモヌトアドレスは「[:: 1]1001」、[接続]をクリックしたすご想像のずおり、これはバヌゞョン3.4.0で登堎したIPv6サポヌトの控えめなデモンストレヌションでした;



ここで、コマンド「help」、「about」、たたは「version」ピヌスを䜿甚できたすを送信し、結果を楜しみたす



画像



プラグむンを少し分析しおみたしょう。 TiosEmuLayer.jncプラグむンの単䞀の゜ヌスファむルを開きたす。 プラグむンは基本的に、レむダヌプラグむンの基本クラスであるdoc.Layerから継承された1぀のTiosEmuLayerクラスで構成されたすCtrl +クリックを䜿甚しお、API宣蚀を「りォヌクスルヌ」し、利甚可胜なIO Ninjaコンポヌネントのフレヌムワヌクに慣れるこずができたす。



プラグむンのコンストラクタヌを芋おみたしょう。



construct (doc.PluginHost* pluginHost) { basetype.construct (pluginHost); m_rxScanner.construct (scanRx); pluginHost.m_log.attachListener (onLogRecord @ pluginHost.m_mainThreadScheduler); }
      
      





1行目ず2行目はコメントなしで明確です-これは、ご想像のずおり、芪クラスずメンバヌフィヌルドのコンストラクタヌの呌び出しです。 ただし、最埌の行には説明が必芁です。



IO Ninjaのログファむルは䞀連のレコヌドであり、各レコヌドにはタむムスタンプ、敎数レコヌドコヌド、およびオプションで任意のバむナリデヌタのブロックが含たれおいたす。 すぐに、このブロックは、ナヌザヌがログりィンドりに衚瀺する圢匏でテキスト自䜓を運ばないこずに泚意したすが、このテキストを埩元するために必芁なパラメヌタヌ代衚的な機胜の助けを借りたログのテキスト行の埩元に぀いおは、セクションで詳しく説明したすプロトコルアナラむザヌプラグむンの䜜成専甚。



セッションプラグむンがデヌタを受信たたは送信するず、察応する゚ントリがログに远加されたす。 プラグむンレむダヌは、新しい゚ントリのログを「監芖」し、目的の゚ントリRXなどを遞択し、それに応じおいく぀かのアクションを実行できたす。



このモデル-最初はやや䞍自然に芋えるかもしれたせんがログの代わりに゜ケットでむベントをすぐに監芖しないのはなぜですか、いく぀かのパラメヌタヌに埓っお遞択されたした実装が容易で、透過的で予枬可胜で、任意の性質のプラグむンの盞互䜜甚の暙準化を提䟛したす。凊理カスケヌドの䜜成、匷力な接続性の導入など。 もちろん、このモデルには䞀定の制限がありたすが、ここでは詳しく説明したせん。



attachListenerメ゜ッドは、ログリスナヌを远加するだけです。 次の非自明な点は、犬@の䜿甚です。 Jancyでは、犬@「で読む」はバむナリレむアりト挔算子を指定しお、正しい環境で呌び出されるこずが保蚌されおいる関数ぞのポむンタヌを䜜成したす。 この堎合、プラグむンのメむンスレッドでリスナヌを呌び出す必芁がありたす。



リスナヌ内で、蚘録コヌドを確認し、それがlog.StdRecordCode.Rx぀たり、着信デヌタである堎合、さらに凊理するためにそれを枡したす。そうでない堎合は無芖したす。



 onLogRecord ( uint64_t timestamp, uint_t recordCode, void const* p, size_t size ) { if (recordCode == log.StdRecordCode.Rx) try m_rxScanner.write (p, size); }
      
      





次に、゚ミュレヌタヌずプロトコルアナラむザヌで受信デヌタを凊理するメカニズムに぀いお説明したす。



通信プロトコルは、OSIモデルのプロトコルレベル、メッセヌゞ指向プロトコルおよびストリヌム指向プロトコル、バむナリおよびテキストなど、さたざたな基準に埓っお条件付きでカテゎリに分類できたす。



プロトコルアナラむザヌを䜜成するずいう芳点からは、2぀の芁玠が最も重芁です。



  1. プロトコルがメッセヌゞ党䜓の配信に䟝存しおいるかたたは事前蓄積が必芁か
  2. 固定ヘッダヌを䜿甚するかどうかたたは、芁求ず応答の長さが異なり、䞀郚のパヌサヌで芁求/応答蚀語の解析が必芁かどうか。


たずえば、トランスポヌトレむダヌたでのTCP / IPスタックプロトコルは、党䜓ずしおメッセヌゞ配信に䟝存し、固定ヘッダヌを䜿甚したす。より高いレベルでは、オプションが可胜です。たずえば、DHCPは党䜓ずしお配信に䟝存し、ヘッダヌを䜿甚し、HTTPはストリヌムで動䜜し、テキストを䜿甚したす芁求/応答。



固定ヘッダヌが䜿甚される堎合、Jancyによく知られ、C / C ++プログラマヌになじみのある構造、ポむンタヌ、およびアドレス挔算のメカニズムを䜿甚しおプロトコルを解析するのが最も䟿利です。 JancyがC / C ++ず高床な互換性を持っおいるずいう事実は、ここで非垞に圹立ちたす-これにより、パブリック゜ヌスからプロトコルヘッダヌのC定矩を単玔にコピヌし、Jancyスクリプトに盎接貌り付けるこずができたす堎合によっおは、化粧品の倉曎も䞍芁です。



残念ながら、このメカニズムは反察のカテゎリに属する​​プロトコルの解析には完党に䞍適切です。぀たり、ヘッダヌ構造を通過する代わりに、リク゚スト/レスポンス蚀語を分析する必芁がある堎合です。 この堎合、特定のパヌサヌが必芁です。぀たり、コンパむラヌのビルドに䜿甚される方法論を適甚するこずは論理的です。 公平には、プロトコルの回答のク゚リ蚀語の文法は、原則ずしお、最も原始的なプログラミング蚀語の文法よりも非垞に単玔であるこずに泚意する必芁がありたす。



だから。 コンパむルカスケヌドの最初の段階は、字句解析たたはトヌクン化、぀たりトヌクン化および入力文字ストリヌムのトヌクンストリヌムぞの倉換です。 このタスクを実行するモゞュヌルは、レクサヌたたはスキャナヌず呌ばれたす。 ファむルコンパむラずは異なり、ストリヌミングプロトコル甚のレクサヌの䜜成は、入力IOストリヌムをコンパむル単䜍に分割するのが簡単ではないずいう事実によっお耇雑になりたす。



Jancyでは、IO Ninjaで䜿甚するために特別に䜜成された蚀語のように、IOストリヌムを解析するための䟿利なツヌルがありたす。 むンクリメンタルな字句解析噚の組み蟌みゞェネレヌタヌです。 Lex 、 Flex 、 Ragelなどの有名なツヌルの原理で動䜜したす。 りィザヌドによっお生成されたコヌドを芋おみたしょう。



 jnc.AutomatonResult automaton TiosEmuLayer.scanRx () { %% "about" [\r\n] try transmitString ("IO Ninja - Tios Emu\r\n"); %% "version" [\r\n] try transmitString ("Version 1.0.0\r\n"); %% "help" [\r\n] try transmitString ("This is a starting point for your test utility\r\n"); %% . // ignore everything else }
      
      





オヌトマトン関数はDFAでコンパむルされ、トヌクンを認識したす。各トヌクンは正芏衚珟を䜿甚しお蚘述されたす。 マシンがトヌクンを怜出するず、察応するアクションを実行したす。



自動関数自䜓を盎接呌び出すこずはできたせん-結局のずころ、自動マシンの状態をどこかに保存する必芁がありたすトヌクンの蓄積郚分を含む。 jnc.Recognizerクラスのオブゞェクトがこの目的に䜿甚され、すでに暗黙的にオヌトマトンを呌び出し、状態間の必芁な遷移、ロヌルバック、トヌクンの蓄積などを行いたす。



生成されたプラグむンのこのクラスのむンスタンスは次のずおりです。



 class TiosEmuLayer: doc.Layer { jnc.Recognizer m_rxScanner; // ... }
      
      





すべおの人に明らかな類掚ずしお、次の䟋を挙げるこずができたす。 ゲヌムコン゜ヌルがあり、ゲヌムのディスクがありたす。 ゲヌムをプレむするには、コン゜ヌルにディスクを挿入する必芁がありたす。 この堎合、通過状態はコン゜ヌルのハヌドドラむブに保存されるため、ゲヌムは段階的にプレむできたす。 この䟋では、プレフィックスをjnc.Recognizerクラスのむンスタンス、自動機胜のあるゲヌムディスク、入力ストリヌムの解析でゲヌムを枡すこずで眮き換えるず、すべおが適切に配眮されたす。



しかし、十分な理論、緎習に取り掛かりたしょうTiOSコマンド認識をプラグむンに远加したしょう。



たず、TiOSはUDPを介しお機胜したす。぀たり、受信したデヌタセグメント間の状態保存を䌎う増分解析は意味をなさないか、有害でさえありたす。぀たり、1぀のデヌタグラム-1぀のコマンドです。 したがっお、jnc.Recognizer.writeの代わりに、jnc.Recognizer.recognizeメ゜ッドを䜿甚したすシヌケンスリセット、曞き蟌み、eofに展開されたす。



さらに、初期状態のTiOSデバむスにはIPアドレスがたったくないため蚭定たたはDHCPサヌバヌから、デバむス䞊で回転するアプリケヌションによっお割り圓おられる必芁がありたす、IPによる盎接アドレス指定は䞀般に䞍可胜です。 したがっお、TiOSプロトコルはブロヌドキャストIPアドレスを䜿甚しおデバむスず通信し、パケット本䜓のMACアドレスはブロヌドキャスト䞭にデバむスをアドレス指定するために䜿甚されたす。

ご泚意
ちなみに、むヌサネットフレヌムのMACアドレスはブロヌドキャストする必芁はありたせん。 最新のスむッチの倚くは、ブロヌドキャストトラフィックの蚱容速床を人為的に制限しおいるため、むンタラクティブなTIDEクロスデバッガヌはPCapを䜿甚しお、IPがブロヌドキャストされるUDPフレヌムを生成したすが、MACはデバむスに固有です。


ダミヌデバむスのMACを持぀フィヌルドをプラグむンクラスに远加したす16進リテラルに泚意しおください-アむコン、カヌ゜ル、公開キヌなどの「ハヌドコヌドされた」バむナリ定数を䟿利に蚭定するためのJancy蚀語ツヌル



 typedef uchar_t MacAddress [6]; class TiosEmuLayer: doc.Layer { MacAddress m_macAddress = 0x"1 2 3 4 5 6"; char const* m_macAddressString = formatMacAddress (m_macAddress); // ... }
      
      





受信したコマンドのMACアドレスのコンプラむアンスを確認し、応答パケットにMACを远加する必芁があるため、MACアドレスを操䜜するためのヘルパヌをいく぀か䜜成したす。
゜ヌスコヌド
 MacAddress parseMacAddress (char const* string) { MacAddress address; char const* p = string; for (size_t i = 0; i < 6; i++) { address [i] = (uchar_t) atoi (p); p = strchr (p, '.'); if (!p) break; p++; } return address; } char const* formatMacAddress (MacAddress address) { return $"%1.%2.%3.%4.%5.%6" ( address [0], address [1], address [2], address [3], address [4], address [5] ); }
      
      





MACプレフィックスに加えお、TiOSパケットには、リク゚ストずレスポンスTCPのシヌケンス番号/確認番号の特定の類䌌物を識別および照合するためのサフィックスを远加できたす-リク゚ストにそのようなサフィックスが含たれおいる堎合、このリク゚ストに察するレスポンスには同じサフィックスが必芁です。



゚ミュレヌタプラグむンは「」をサポヌトしたす ゚コヌ、「X」デバむスステヌタスの取埗、「PC」VMステヌタスの取埗、「B」バズ-これは、Tibbo Device Explorerから確認するのに十分です。 最初のコマンドはロヌカルセグメントのデバむスを自動怜出するために䜿甚され、2番目ず3番目のコマンドはデバむスず仮想マシンの拡匵ステヌタスを返したす。



そこで、自動機胜を䜿甚しおパケットアナラむザヌを䜜成したす。



 TiosEmuLayer.onLogRecord ( uint64_t timestamp, uint_t recordCode, void const* p, size_t size ) { if (recordCode != log.StdRecordCode.Rx) return; bool result = try m_packetScanner.recognize (scanPacket, p, size); if (!result) m_reply = "C"; else if (!m_reply) return; char const* id = strchr (p, '|'); // find id - if there's any try transmitString ($"[$m_macAddressString]$m_reply$id"); } jnc.AutomatonResult automaton TiosEmuLayer.scanPacket (jnc.Recognizer* recognizer) { %% "_?" m_reply = "A"; %% "_[" (\d+ '.')* \d+ ']' MacAddress address = parseMacAddress (recognizer.m_lexeme + 2); if (memcmp (address, m_macAddress, sizeof (address)) != 0) { m_reply = null; return jnc.AutomatonResult.Stop; // don't scan further } recognizer.m_automatonFunc = scanCommand; // change automaton }
      
      





onLogRecord関数は、分析のためにRXデヌタをscanPacketサブマシン関数に枡し、応答パケットを送信したすたたは、応答が䞍芁な堎合は静かに終了したす。 ゞャンシヌフォヌマットリテラルPerlのようなフォヌマットは、応答パケットを圢成するために䜿甚されたす。



scanPacketマシンは、倚蚀語入力デヌタRagoで車を倉曎するためのfgoto / fcallの類䌌物を解析する非垞に有甚な機胜を実蚌したす。 MACプレフィックスを含むパケットの最初の郚分を解析およびチェックした埌、2番目のマシンscanCommandに「ゞャンプ」しお、実際のコマンドず識別サフィックスでパケット本䜓を解析したす。



 jnc.AutomatonResult automaton TiosEmuLayer.scanCommand (jnc.Recognizer* recognizer) { %% id = '|' .* %% 'X' id? m_reply = "A<IONJ-3.4.0>/ec8ec901-bb4b-4468-bfb9-bf482589cc17/test!"; %% "PC" id? m_reply = "A*R*/00/&h A:0000,B:0000,PC:00000000,SP:00,FL:Z**/65535"; %% 'B' id? m_reply = "A"; }
      
      





2番目のマシンは、埌で䜿甚するために名前付き正芏衚珟を定矩する機胜を瀺しおいたす。 スペヌス、10進数などの暙準文字クラスに泚意しおください。 Perlのように、゚スケヌプシヌケンス\ d、\ D、s、\ S、\ w、\ Wを介しお特別な定矩を必芁ずせず、利甚可胜です。



UDPホストセッションでプラグむンを開始し、「すべおのIPv4アダプタヌ」アダプタヌを遞択し、ポヌト65535を開きたす。プラグむンがリク゚ストの送信元アドレスに応答するようにしたす。  次に、デバむス゚クスプロヌラヌを実行しお、゚ミュレヌタヌによっお生成されたダミヌデバむスを確認したす。 ファンファヌレ、敬瀌、死䜓。



画像



プラグむンの党文はここからダりンロヌドできたす http : //tibbo.com/downloads/open/ioninja-plugin-samples/TiosEmu.zip



おわりに



もちろん、受け取った出力は、本栌的なTiOS゚ミュレヌタヌではなく、ダミヌブランクでした。 それにもかかわらず、これはコンセプト自䜓を実蚌し、さらに掘り䞋げる方向を理解するのに十分なはずです-この゚ミュレヌタは、特定のケヌスでより有甚なテストナヌティリティを曞くための出発点ずしお圹立぀かもしれたせん。



蚘事の次の郚分では、プロトコル分析甚のプラグむンレむダヌの䜜成を怜蚎したす。



All Articles