How to Plug into Message Analyzer Parsers

Message Analyzer has an open plug-in model of which developers can take advantage to parse network payloads they might provide as part of ETW logging. By simply providing a payload as a field of your ETW data, Message Analyzer can parse the payload starting at any layer of the network stack.

Open Protocol Notation

OPN is the name of the language that is used to parse and model protocols in Message Analyzer. It is similar to the C# language with constructs that support the modeling aspects of the language, or protocol simulation. As a model, OPN can certainly parse the network traffic data, but additional code can make your model “Act” like the protocol. So OPN Actors can also simulate the behavior of a protocol if you want. This advantage enables extremely deep analysis of behaviors, which you pay for in performance when loading a trace. To mitigate this, you can expose parameters you set through the UI, which lets the user enable the protocol specific diagnosis.

The OPN Programming Guide is a reference that can help you learn the language vocabulary and it also provides more examples.


There is an easy example of hooking up the Ethernet protocol in the OPN code we ship that is called SuppRasNdis.opn. This OPN file is stored in the following directory location:

%LocalAppData%\Microsoft\MessageAnalyzer\OPNAndConfiguration\ OPNForEtw\CoreNetworking\


$env:LocalAppdata\Microsoft\MessageAnalyzer\OPNAndConfiguration\ OPNForEtw\CoreNetworking\

. . for PowerShell folks.

The following shows the code in SuppRasNdis.opn file, which you can locate in the above specified path:

module SuppRasNdis;

using Microsoft_Windows_Ras_NdisWanPacketCapture;
using Standard;
using Utility;
using Etw;
using EtwEvent;
using WindowsReference;
using Ethernet;

// Etherenet over RasDNIS ETW actor
autostart actor EthernetOverRasNDIS(ep_Microsoft_Windows_Ras_NdisWanPacketCapture e)
    // Decodes the payload as Ethernet
    process e accepts m:Event_5001
        switch (m.Fragment)
            case f:Ethernet.Frame from BinaryDecoder<Ethernet.Frame[false]> =>
                dispatch (endpoint Ethernet.Node) accepts f;

    // Decodes the payload as Ethernet
    process e accepts m:Event_5002
        switch (m.Fragment)
            case f:Ethernet.Frame from BinaryDecoder<Ethernet.Frame[false]> =>
                dispatch (endpoint Ethernet.Node) accepts f;

The Actor is called EthernetOverRasNDIS. It receives messages from another message endpoint, which is defined in the Microsoft_Windows_Ras_NdisWanPacketCapture provider. This code is automatically generated by the Message Analyzer runtime. We can take a look at the generated OPN for the ETW provider if we want to find out the actual endpoint name, but the generated endpoint name contains an “ep_” prefix followed by the component/provider name, as in ep_Component_Long_Name_Here.

The Actor, which is set to autostart, has process rules. If the autostart modifier is not used, then some OPN code would have to put the Actor into a listening state and then start it. Each process rule qualifies the message it will react to. Next, the message field Fragment, which is the Ethernet payload, is evaluated as a binary blob using the BinaryDecoder.

The BinaryDecoder could be a XMLDecoder or ANS1Decoder, if your data is not Binary. The decoder specifies a Message type as a parameter, in this case Ethernet.Frame. The message can validate or invalidate the decoder call, by adding aspects to field definitions, thus allowing you to check the data and types before dispatching the message. The argument to Ethernet.Frame message tells if this is a truncated message or not.

Finally, the fragment is dispatched to the next endpoint, which the Ethernet.opn description defines as Node. It accepts f, which is an alias for Ethernet.Frame. Accepts indicates the direction we defined for Ethernet. But as direction is not relevant to parsing the Ethernet protocol, it doesn’t matter. There is also Issues, being the opposite of Accepts, and these two directional constructs allow you to define client/server roles of protocol modeling.

Hooking up your Code

You can create your new OPN and copy it to the EtwForOPN directory or any subdirectory. This special directory is examined when a new ETW provider is loaded. Message Analyzer scans the EtwForOPN directory and subdirectories for code dependent on the message provider being loaded, as specified in the above Using statements. Don’t make the mistake of placing your OPN that is meant to work with ETW in the regular OPN directory, as strange things can ensue.

Errors are reported in the Message Analyzer log file, so when Message Analyzer is restarted and your code compiled, you can open the log and try to understand what went wrong. A restart of Message Analyzer is necessary to see new changes. Also if you have a saved MATP file from Message Analyzer, it’s saved with parsing information, so loading an MATP file doesn’t trigger a recompile when testing your code. Instead, use Logman or some other tool to collect your traffic, and save as an ETL file. Loading the ETL in Message Analyzer will trigger the code to recompile when you make changes. An example of using Logman is:

logman start trace MySession -p "{123449E6-2A2C-46E4-9167-FA122525D540}" 0xFFFFFFFF 0x5 -ets

then to stop it:

logman stop trace MySession

Extending Message Analyzer

There are many ways to extend Message Analyzer. Authoring OPN for components that emit Ethernet or other network messages is a simple extensibility project. Give it a try, and if you run into issues, feel free to contact us on the Forums.

Comments (2)

  1. Aditya says:

    I have a question regarding this. According to this, can I write an own plugin which for example performs the following: displays the statistics, display check sum, export the files and save into .csv format and other additional features and then integrate the plugin into Message Analyzer.
    Thank you.

  2. Paul E Long says:

    Yes, this should be possible. If you need help, the support forum is a great place to start.


Skip to main content