Generic TCP Module
The Generic TCP Module builds on the Web Response Time Module API framework to provide a simple configuration file approach to protocol decoding. The configuration file format is an extension of the normal Web Response Time Module API XML configuration file.
Basic Generic TCP Module configuration
<module>
<name>generic</name>
…
</module>Filters and context output
<filter>
<port>21</port>
</filter>
<input>
</input>
<output>
<context>
<item>
<name>tcp.protocol</name>
<type>string</type>
</item>
<item>
<name>ftp.client.name</name>
<type>string</type>
</item>
<item>
<name>ftp.command</name>
<type>string</type>
</item>
<item>
<name>ftp.responsecode</name>
<type>string</type>
</item>
</context>
</output>In this example, the decoder requests TCP data from port 21 (FTP), and produces four items of context (tcp.protocol, ftp.client.name, ftp.command and ftp.responsecode).
Protocol definitions and actions
<config>
<section name="rules">
NonCRLFChar = VCHAR / SP
CRLFTerminatedString = *NonCRLFChar CRLF
; Basic request flow
FTP_Session = <ENTRYPOINT> FTP_Banner *FTP_Transaction <END_OF_STREAM>
; The main loop
FTP_Banner = FTP_Responseline
; A transaction is a request followed by a response
FTP_Transaction = FTP_Requestline FTP_Responseline
; Request lines are read from the request stream
; All requests are single lines terminated with CRLF
FTP_Requestline = <FROM REQUEST_STREAM> CRLFTerminatedString
; Response lines are read from the response stream
; Responses may be single line or multi line responses
FTP_Responseline = <FROM RESPONSE_STREAM> FTP_SingleLineResponse /
FTP_MultiLineResponse
FTP_SingleLineResponse = 3DIGIT SP CRLFTerminatedString
; Single line response is nnn <message>
FTP_MultiLineMiddle = CRLFTerminatedString
FTP_MultiLineResponse = 3DIGIT "-" CRLFTerminatedString
; Multi line response is nnn-<message>
*FTP_MultiLineMiddle
; zero or more text lines
FTP_SingleLineResponse
; Terminated by a normal nnn <message>
;
; Deeper decoding
;
; FTP_Request extends the FTP_Requestline rule
FTP_Request = <FROM RULE FTP_Requestline> FTP_Commands CRLF
; Strip the CRLF
; By separating Command and Unknown_Command here,
; we can extend FTP_Command is subsequent rules
FTP_Unknown_Command = FTP_Unknown *NonCRLFChar
; Entire command is unknown but not necessarily
; bad. We just don't know/care about it
FTP_Unknown = 1*ALPHA
FTP_Commands = FTP_Command / FTP_Unknown_Command
FTP_Command = FTP_RETR_Command / FTP_STOR_Command / FTP_USER_Command
/ FTP_LIST_Command
FTP_RETR_Command = "RETR" 1*WSP FTP_Get_Filename
FTP_Get_Filename = *NonCRLFChar
; End will consume to the end of the current input
; In this case, that is the end of FTP_Requestline
FTP_STOR_Command = "STOR" 1*WSP FTP_Put_Filename
FTP_Put_Filename = *NonCRLFChar
FTP_USER_Command = "USER" 1*WSP FTP_Username
FTP_Username = *NonCRLFChar
FTP_LIST_Command = "LIST" 1*WSP FTP_ListParameters
FTP_ListParameters = *NonCRLFChar
; Response Handling
FTP_Reply = <FROM RULE FTP_SingleLineResponse> FTP_ResponseCode SP
CRLFTerminatedString
; How do you like your responses reporteds ?
FTP_ResponseCode = 3DIGIT
; Single context with all codes
</section>
<section name="action:FTP_Username">
session.command = "USER " .. MATCH
session.ctxname = "ftp.client.name"
session.ctxval = MATCH
</section>
<section name="action:FTP_Unknown">
session.command = "ftp.command"
session.ctxname = "ftp.command"
session.ctxval = MATCH
</section>
<section name="action:FTP_Get_Filename">
session.command = "GET " .. MATCH
session.ctxname = "ftp.get.filename"
session.ctxval = MATCH
</section>
<section name="action:FTP_Put_Filename">
session.command = "PUT " .. MATCH
session.ctxname = "ftp.put.filename"
session.ctxval = MATCH
</section>
<section name="action:FTP_ListParameters">
session.command = "LIST"
session.ctxname = "ftp.list.parameters"
session.ctxval = MATCH
</section>
<section name="action:FTP_ResponseCode">
session.responsecode = MATCH
</section>
<section name="action:FTP_Transaction">
set_context("tcp.protocol", "ftp")
set_context("ftp.command", session.command);
set_context(session.ctxname, session.ctxval)
set_context("ftp.responsecode", session.responsecode)
send_data()
</section>
</config>The first config section defines the logical structure of the protocol to be decoded. This definition is encoded as a CDATA block containing Augmented Backus-Naur Form (ABNF) rules describing the protocol. ABNF (defined in RFC 5234) is a format commonly used to define protocol structure in RFC documents. The generic decoder uses these rule definitions to decode packet data. As ABNF definitions do not normally include directional semantics (for example, server sends X, client sends Y) several directives are provided by the Generic TCP Module to indicate flow information in the rule definitions. These are declared as ABNF prose values (indicated by surrounding brackets, < >). Following the rule definitions, a series of action sections are used to map rule matches to output context values.