View on
Steffen Ullrich > Net-IMP-0.54 > Net::IMP::ProtocolPinning



Annotate this POD


Open  0
View/Report Bugs
Source   Latest Release: Net-IMP-0.634


Net::IMP::ProtocolPinning - IMP plugin for simple protocol matching


    my $factory = Net::IMP::ProtocolPinning->new_factory( rules => [
        # HTTP request from client (dir=0)
        [ 0,9,qr{(GET|POST|OPTIONS) \S} ],

    my $factory = Net::IMP::ProtocolPinning->new_factory( rules => [
        # SSHv2 prompt from server
        [ 1,6,qr{SSH-2\.} ],

    my $factory = Net::IMP::ProtocolPinning->new_factory(
        rules => [
            # SMTP initial handshake
            # greeting line from server
            { dir => 1, rxlen => 512, rx => qr{220 [^\n]*\n} },
            # HELO|EHLO from client
            { dir => 0, rxlen => 512, rx => qr{(HELO|EHLO)[^\n]*\n}i },
            # response to helo|ehlo
            { dir => 1, rxlen => 512, rx => qr{250-?[^\n]*\n} },
        # some clients send w/o initially waiting for server
        ignore_order => 1,
        max_unbound => [ 1024,0 ],


Net::IMP::ProtocolPinning implements an analyzer for very simple protocol verification using rules with regular expressions. The idea is to only check the first data in the connection for protocol conformance and then let the rest through without further checks.

Calls to new_factory or new_analyzer can contain the following arguments specific to this module:

rules ARRAY

Specifies the rules to use for protocol verification. Rules are an array of direction specific rules, e.g. each rule consists of [dir,rxlen,rx] with


the direction, e.g. 0 for data from client and 1 for data from server


the length of data the regular expression might need for the match. E.g. if the regex is qr/foo(?=bar)/ 6 bytes are needed for a successful match, even if the regex matches only 3 bytes.


the regular expression itself. The regex will be applied against the not-yet-forwarded data with an implicit \A in front, so look-behind will not work.

ignore_order BOOLEAN

If true, it will take the first rule for direction, when data for connection arrive. If false, it will cause DENY if data arrive from one direction, but the current rule is for the other direction.

max_unbound [SIZE0,SIZE1]

If there are no more active rules for direction, and ignore_order is true, then the application needs to buffer data, until all remaining rules for the other direction are matched. Using this parameter the amount of buffered data which cannot be bound to a rule will be limited per direction.

If not set a default of unlimited will be used!

Process of Matching Input Against Rules

Rules for Writing the Regular Expressions

Because the match will be tried whenever new data come in (e.g. the buffer might have a size of less than, equal to or greater than rxlen), care should be taken, when constructing the regular expression and determining rxlen. It should not match data longer than rxlen, e.g. instead of specifying \d+ one should specify a fixed size with \d{1,10}.

Care should also be taken if you have consecutive rules for the same direction (e.g. either the next rule is for the same direction or ignore_order is true). Here you need to make sure, that the first rule will not match data needed by the next rule, e.g. \w{1,2} followed by \d will not work, while [a-z]{1,2} followed by \d will be fine.

Please note also, that the regular expression in the rule will be implicitly anchored at the beginning of the buffered data, e.g. \d will only match if the first character is a digit, not if any character but the first in the buffer is a digit. If you want the latter behavior, you have to explicitly allow other characters and need to limit their amount, e.g. "(?s).{0,10}\d".


Steffen Ullrich <>


Copyright by Steffen Ullrich.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

syntax highlighting: