How to add a protocol to the supported ones


This operation is divided in three steps:

  1. Definition of the protocol by modifying the PDF file.
  2. Definition of the protocol fields printed on the screen  by modifying the DFF file.
  3. Definition of the protocol printed in the packet index by modifying the IFF file.

More information about PDF, DFF, IFF files can be found into the Protocol definition Section.

This Section will provide an example of the steps needed to add new protocols. We will add three protocols in order to explain these steps:

We will modify the protocol configuration files (PDF file, DFF file, IFF file) in order to add these protocols. Initial PDF, DFF and IFF files have been kept quite small in order not to increase the difficulties of the task.

All the instructions used in these files are described by their relative grammars.

Instructions devoted to retrieve information about the packet (for example the value of a particular field) are resolved by means of a virtual machine that reads the packet.

 

Protocol Definition File: default.pdf

The MAC protocol definition is embedded between the key words PROTOCOL and ENDPR; For example, Ethernet v.2.0 header can be written as:

PROTOCOL MAC
WORD DS1 /* DSAP */
WORD DS2
WORD DS3

WORD SS1 /* SSAP */
WORD SS2
WORD SS3

WORD LEN_TYPE /* Data Length or Protocol Type */
ENDPR

MAC protocol is used also to determine which is next protocol. Instructions that allows doing that are case and else. For instance:

case LEN_TYPE<=1500: LLC
else UNSUPPORTED

The, it follow the LLC protocol definition:

PROTOCOL LLC
BYTE DSAP
BYTE SSAP
BYTE CONTROL
ENDPR

Instruction case is not compulsory; vice versa instruction else does:

else UNSUPPORTED

The following rows define a fake protocol called 'Unsupported'; this protocol does not really exist but it is used to exit from the analysis. The instruction skip means "skip the following N bytes, then restart parsing the remaining part of the packet". In order to finish the analysis, 'skip' instruction has to be followed by a very large number (bigger than the biggest packet size of the network) in order to be sure that end of packet has been reached. The instruction 'else' is followed by the name of the same fake protocol.

The keyword virtual prevents the user from using the protocol fields (which do not even exist in this case) in the expressions; virtual protocols cannot be used in DFF and IFF files.

VIRTUAL PROTOCOL UNSUPPORTED
ENDPR
skip: 20000
else UNSUPPORTED

 

Protocol Description File: default.dff

The file default.dff contains six functions definitions:

  1. PartialFrame(){...}
  2. Main(){...}
  3. DATA(){...}
  4. UNSUPPORTED(){...} //correspondent to unsupported protocols
  5. MAC (){...}        //correspondent to  MAC protocol
  6. LLC (){...}        //correspondent to LLC protocol

The last three functions are relative to the protocols defined in default.pdf; in fact each protocol must have a relative function, declared in PDF file, which is called when its protocol is parsed.

When a packet has to be displayed, function main is called first that prints general information. Detailed information are printed by other functions, whose name coincides with the one defined into the PDF file. For instance, defining a protocol called MAC in default.pdf, we have to define a function MAC in default.dff and default.iff in order to print information about this level. Whem a protocol is located by the PDF definition the correspondant DFF/IFF function is called; if the function does not exist the content of the fields defined in the PDF is displayed. Such a function has the visibility of its own-defined variables and fields defined in the PDF; this functions can read, print and to modify these fields like standard variables.

PartialFrame()

It is invoked by the 'main' function. It prints the available bytes number and the length of the packet read from the disk. Both value are obtained through the call of the function GetVmVar(). printf() behaves like the homonymous C function.

DWORD PartialFrame()
{
    title ("Description");
    printf( "Item type: Partial frame, %u bytes available", GetVMVar ("FrameAvail"));
    printf( "Frame size is %u (%X hex) bytes",GetVMVar ("FrameSize"),GetVMVar ("FrameSize"));

Main()

It prints some general information about the packet; it is similar to the homonymous C function:

DWORD Main()
{
title("General");
    printf("Item number %u, position in logfile %u%%",GetVMVar ("ItemNumber"),GetVMVar ("Position")); 
if (GetVmVar("FrameSecs")==0) printf("Timestamp: 00h:00m:00s:%06dus",GetVMVar ("FrameUSecs"));
else
printf( "Timestamp: %02dh:%02dm:%02ds:%06dus",(GetVMVar ("FrameSecs")%86400)/3600+2,
(GetVMVar ("FrameSecs")%3600)/60,GetVMVar ("FrameSecs")%60,GetVMVar ("FrameUSecs"));
PartialFrame();
}

Data()

It prints two values obtained by invoking GetVMVar() function. In this example data() is called as soon as the LLC analysis finishes, because no other protocols are defined after LLC. Whether current packet does not have an LLC level then the analysis goes to the UNSUPPORTED protocol; so function Unsupported is called and the analysis ends without calling the data function. 

DWORD DATA()
{
  DWORD s,t;
  s=GetVMVar ("SizeNotInt");
  t=GetVMVar ("FrameSize");
  if (s)
  {
  printf("----- Data ----- [%d-%d]",t-s,t-1);
  printf( "[%u byte(s) of data]",s);
  }
}

Unsupported()

It prints two values obtained invoking GetVmVar:

DWORD UNSUPPORTED()
{
  DWORD s,t;
  s=GetVMVar ("SizeNotInt");
  t=GetVMVar ("FrameSize");
  if (s)
  {
  printf("----- NOT SUPPORTED ----- [%d-%d]",t-s,t-1);
  printf( "[%u byte(s) of data]",s);
  }
}

MAC()

We notice the instruction 'offset' which returns the offset of the specified field.

DWORD MAC ()
{
    // MAC analysis
    if (LEN_TYPE<=1500) title( "IEEE 802.3 MAC Header");
    else title("Ethernet v.2.0 MAC Header");

    printf( "Destination = %04X%02X-%02X%04X",DS1,DS2>>8,DS2&0xFF,DS3);
    printf( "Source = %04X%02X-%02X%04X", SS1,SS2>>8,SS2&0xFF,SS3);

    if(LEN_TYPE<=1500) {	// IEEE 802.3 format
       DWORD padding;
       printf( "Packet Length = %u bytes",LEN_TYPE);
       padding=GetVMVar ("FrameSize")-(LEN_TYPE+14);
       if(padding!=0)printf("Padding bytes %u (before data)",padding);
    }
    else			// Ethernet format (DIX)
       printf( "Ethertype = %04Xh (%p)",LEN_TYPE,offsetof(LEN_TYPE));
}

LLC()

DWORD LLC ()
{
    //continues analysis of a IEEE 802.3 frame with the LLC level
    title( "LLC Header");
    printf( "DSAP = %02Xh (%l)",DSAP,offsetof(DSAP));
    printf( "SSAP = %02Xh (%l)",SSAP,offsetof(SSAP));
    //analysing control field
	if (CONTROL==0 || CONTROL==1)     //information frame
	    printf( "Control = Information frame");
	else if (CONTROL==2)              //supervisory frame
	    printf( "Control = Supervisory frame");
	else if (CONTROL==3)              //unnumbered frame
	    printf( "Control = Unnumbered frame");
}

Protocol Index File: default.iff

As you can read in Protocol codification in Analyzer this file defines the packets index print; so it is an abstract of the DFF file, in fact it generates the print of the packet information which are considered essential. The language is the same used in DFF file.

DWORD Main()
{
    if (GetVmVar("FrameSecs")==0) printf("00h:00m:00s:%06dus",GetVMVar ("FrameUSecs"));
    else
        printf( "%02dh:%02dm:%02ds:%06dus",(GetVMVar ("FrameSecs")%86400)/3600+2,
               (GetVMVar ("FrameSecs")%3600)/60,GetVMVar ("FrameSecs")%60,GetVMVar ("FrameUSecs"));
}

DWORD MAC () {
    // MAC analysis
    printf( "%04X%02X-%02X%04X", DS1,DS2>>8,DS2&0xFF,DS3);
    printf( "%04X%02X-%02X%04X", SS1,SS2>>8,SS2&0xFF,SS3);
}

To see the output produced by Analyzer using these three files, set them in window protocol definition and open a capture file.

 


Adding IPX protocol

The following modification have to be implemented:

  1. Definition of the new protocol (field formats)
  2. Definition of the protocol fields print on the screen
  3. Definition of the summary printed by that protocol in the packet index 

 

Protocol definition

We have to modify the default PDF file. Steps are:

Here it is the IPX protocol structure:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Checksum Length
Transport Control Packet Type Dest. Network Address
Dest. Network Address Dest. Node Address
Dest. Node Address
Dest. Socket Source Network Address
Source Network Address Source Node Address
Source Node Address
Source Socket ...
Data (0-546 byte)

 

The inclusion of the IPX protocol is done adding these rows:

PROTOCOL IPX
	WORD Checksum
	WORD PLen
	BYTE TControl
	BYTE PType
	DWORD DNet
	WORD DNode1
	WORD DNode2
	WORD DNode3
	WORD DSocket
	DWORD SNet
	WORD SNode1
	WORD SNode2
	WORD SNode3
	WORD SSocket
ENDPR
	else UNSUPPORTED

The row "else UNSUPPORTED" at the end of IPX means that no further protocols are recognized after IPX. We can notice that in IPX protocol the fields Source Node and Destination node are 6 bytes long; however PDF files allows only 1 or 2 or 4 bytes long fields. The solution is given by breaking these 6 bytes long fields: we can get three  2 bytes long fields (WORD), one 4 bytes long (DWORD) and one 2 bytes long ( WORD). These two solutions are equivalent for the analysis engine.

For instance, if we want to locate all packets with Source Node field = 123456789ABC (hexadecimal value), the discriminative expression will be:

First solution: SNode1=0x1234 && SNode2=0x5678 && SNode3=0x9ABC
Second solution: SNode12=0x12345678 && SNode3=0x9ABC

For integrating completely the IPX protocol we have to modify also definitions of MAC and LLC protocols (we don't consider proprietary solution which insert IPX in 802.3 payload). MAC level indicates an IPX packet whether field LEN_TYPE == 0x8137 or 0x8138. Then we have to add 2 rows in MAC protocol definition  before string "else UNSUPPORTED":

PROTOCOL MAC
	WORD DS1 /* DSAP */
	WORD DS2
	WORD DS3

	WORD SS1 /* SSAP */
	WORD SS2
	WORD SS3

	WORD LEN_TYPE /* Data Length or Protocol Type */
ENDPR
	case LEN_TYPE<=1500: LLC
	case LEN_TYPE=0x8137: IPX
	case LEN_TYPE=0x8138: IPX
	else UNSUPPORTED

In the LLC header we have to test the field DSAP; if DSAP is equal to 0xe0, next protocol will be IPX:

PROTOCOL LLC
	BYTE DSAP
	BYTE SSAP
	BYTE CONTROL
ENDPR
	case DSAP=0xe0: IPX
	else UNSUPPORTED

We still do not add CASE instructions in IPX definition because there are not protocols (among the defined ones) which succeed to the IPX protocol.

Protocol print definition

We insert a function (DWORD IPX()) in DFF file in order to show the content of IPX packet. This function is composed by a series of printf() and a single instruction title(). Last instruction is used to print the string and create a new section of the packet in order to keep packet information logically organized.

//IPX packet Interpretation
DWORD IPX ()
{
    title("IPX Header");
    printf( "Checksum 0x%X",Checksum);
    printf( "Packet length %u",PLen);
    printf( "Transport control %u",TControl);
    printf( "Packet type 0x%X (%r)",PType,offsetof(PType));
    printf( "Destination network 0x%08X",DNet);
    printf( "Destination node %04X%02X-%02X%04X (Vendor: %v)",
		DNode1,(DNode2>>8),DNode2&0xff,DNode3,offsetof(DNode1));
    printf( "Destination socket 0x%04X (%n)",DSocket,offsetof(DSocket));
    printf( "Source network 0x%08X",SNet);
    printf( "Source node %04X%02X-%02X%04X (Vendor: %v)",
		SNode1,SNode2>>8,SNode2&0xff,SNode3,Offsetof(SNode1));
    printf( "Source socket 0x%04X (%n)",SSocket,offsetof(SSocket));
}

Index packet print definition

We can take the function added in DFF file, eliminate the unnecessary parts and insert it in IFF file. In fact in the index only the main information are shown. Character ":|:" that is printed at the ed of the function tells Analyzer that next printed information must be inserted in the next column (index view is made up of several columns).

//IPX packet Interpretation
DWORD IPX ()
{
    printf("IPX: ");
    printf( "0x%08X.0x%04X",SNet,SSocket);
    printf("=>");
    printf( "0x%08X.0x%04X :|:",DNet,DSocket);
}

Improving the IPX definition

In the definition we did not consider that the IPX header can be contained in the IEEE 802.3 header. In this solution IPX protocol replace LLC protocol.

We can distinguish if the next protocol is IPX or LLC thanks to these two observations:

Then we insert a 'virtual' protocol, called LLC_IPX; this virtual protocol is called if the field 'Data Length or Protocol Type' is less than 1500 (i.e. type is 802.3). In this case the next two bytes are stored in the word PCHECK and they are checked to decide if the next protocol is LLC or IPX. The instruction SKIP -2 is inserted in order to go two bytes back in the packet parsing in order to allow these two bytes being reinterpreted by the following protocol definition. The number after SKIP indicates how many bytes are skipped: 'SKIP N' the reading point goes N bytes on, 'SKIP -N' the reading point goes N bytes back.

VIRTUAL PROTOCOL LLC_IPX
	WORD PCHECK
ENDPR
	skip: -2
	case PCHECK=0xFFFF: IPX
	else LLC

We  modify also MAC definition:

PROTOCOL MAC
	WORD DS1 /* DSAP */
	WORD DS2
	WORD DS3

	WORD SS1 /* SSAP */
	WORD SS2
	WORD SS3

	WORD LEN_TYPE /* Data Length or Protocol Type */
ENDPR
	case LEN_TYPE<=1500: LLC_IPX
	case LEN_TYPE=0x8137: IPX
	case LEN_TYPE=0x8138: IPX
	else UNSUPPORTED

 

Final result

Now the IPX protocol definition is completed. You can try to set these three files in Analyzer using the dialog window Analyzer setup (menu Setup / analyzer); the objects files will be named default.pdo/dfo/ifo and they will be stored in folder Objects.

Default.pdf

PROTOCOL MAC
	WORD DS1 /* DSAP */
	WORD DS2
	WORD DS3

	WORD SS1 /* SSAP */
	WORD SS2
	WORD SS3

	WORD LEN_TYPE /* Data Length or Protocol Type */
ENDPR
	case LEN_TYPE<=1500: LLC_IPX
	case LEN_TYPE=0x8137: IPX
	case LEN_TYPE=0x8138: IPX
	else UNSUPPORTED

VIRTUAL PROTOCOL LLC_IPX
	WORD PCHECK
ENDPR
	skip: -2
	case PCHECK=0xFFFF: IPX
	else LLC

PROTOCOL LLC
	BYTE DSAP
	BYTE SSAP
	BYTE CONTROL
ENDPR
	case DSAP=0xe0: IPX
	else UNSUPPORTED

PROTOCOL IPX
	WORD Checksum
	WORD PLen
	BYTE TControl
	BYTE PType
	DWORD DNet
	WORD DNode1
	WORD DNode2
	WORD DNode3
	WORD DSocket
	DWORD SNet
	WORD SNode1
	WORD SNode2
	WORD SNode3
	WORD SSocket
ENDPR
	else UNSUPPORTED

Default.dff

DWORD PartialFrame()
{
    title ("Description");
    printf( "Item type: Partial frame, %u bytes available", GetVMVar ("FrameAvail"));
    printf( "Frame size is %u (%X hex) bytes",GetVMVar ("FrameSize"),
GetVMVar ("FrameSize"));
}

DWORD Main()
{
    title("General");
    printf("Item number %u, position in logfile %u%%",GetVMVar ("ItemNumber"), GetVMVar ("Position")); 
    if (GetVmVar("FrameSecs")==0) printf("Timestamp: 00h:00m:00s:%06dus", GetVMVar ("FrameUSecs"));
    else 
      printf( "Timestamp: %02dh:%02dm:%02ds:%06dus", (GetVMVar ("FrameSecs")%86400)/3600+2,
		(GetVMVar ("FrameSecs")%3600)/60,GetVMVar ("FrameSecs")%60, GetVMVar ("FrameUSecs"));
    
    PartialFrame();
}

DWORD DATA()
{
    DWORD s,t;
    s=GetVMVar ("SizeNotInt");
    t=GetVMVar ("FrameSize");
    if (s) {
        printf("----- Data ----- [%d-%d]",t-s,t-1);
        printf( "[%u byte(s) of data]",s);
    }
}

DWORD UNSUPPORTED()
{
    DWORD s,t;
    s=GetVMVar ("SizeNotInt");
    t=GetVMVar ("FrameSize");
    if (s) {
        printf("----- NOT SUPPORTED ----- [%d-%d]",t-s,t-1);
        printf( "[%u byte(s) of data]",s);
    }
}

DWORD MAC ()
{
    // MAC analysis
    if (LEN_TYPE<=1500) title( "IEEE 802.3 MAC Header");
    else title("Ethernet v.2.0 MAC Header");

    printf( "Destination = %04X%02X-%02X%04X",DS1,DS2>>8,DS2&0xFF,DS3);
    printf( "Source = %04X%02X-%02X%04X", SS1,SS2>>8,SS2&0xFF,SS3);

    if(LEN_TYPE<=1500) {	// IEEE 802.3 format
       DWORD padding;
       printf( "Packet Length = %u bytes",LEN_TYPE);
       padding=GetVMVar ("FrameSize")-(LEN_TYPE+14);
       if(padding!=0)printf("Padding bytes %u (before data)",padding);
    }
    else			// Ethernet format (DIX)
       printf( "Ethertype = %04Xh (%p)",LEN_TYPE,offsetof(LEN_TYPE));
}

DWORD LLC_IPX ()
{
	if (PCHECK == 65535) printf("IPX on 802.3");
}

DWORD LLC ()
{
    //continues analysis of a IEEE 802.3 frame with the LLC level
    title( "LLC Header");
    printf( "DSAP = %02Xh (%l)",DSAP,offsetof(DSAP));
    printf( "SSAP = %02Xh (%l)",SSAP,offsetof(SSAP));
    //analysing control field
	if (CONTROL==0 || CONTROL==1)     //information frame
	    printf( "Control = Information frame");
	else if (CONTROL==2)              //supervisory frame
	    printf( "Control = Supervisory frame");
	else if (CONTROL==3)              //unnumbered frame
	    printf( "Control = Unnumbered frame");
}

//IPX packet Interpretation
DWORD IPX ()
{
    title("IPX Header");
    printf( "Checksum 0x%X",Checksum);
    printf( "Packet length %u",PLen);
    printf( "Transport control %u",TControl);
    printf( "Packet type 0x%X (%r)",PType,offsetof(PType));
    printf( "Destination network 0x%08X",DNet);
    printf( "Destination node %04X%02X-%02X%04X (Vendor: %v)",
		DNode1,(DNode2>>8),DNode2&0xff,DNode3,offsetof(DNode1));
    printf( "Destination socket 0x%04X (%n)",DSocket,offsetof(DSocket));
    printf( "Source network 0x%08X",SNet);
    printf( "Source node %04X%02X-%02X%04X (Vendor: %v)",
		SNode1,SNode2>>8,SNode2&0xff,SNode3,Offsetof(SNode1));
    printf( "Source socket 0x%04X (%n)",SSocket,offsetof(SSocket));
}

Default.iff

DWORD Main()
{
   if (GetVmVar("FrameSecs")==0) printf("00h:00m:00s:%06dus",GetVMVar ("FrameUSecs"));
   else
      printf( "%02dh:%02dm:%02ds:%06dus",(GetVMVar ("FrameSecs")%86400)/3600+2,
	(GetVMVar ("FrameSecs")%3600)/60,GetVMVar ("FrameSecs")%60, GetVMVar ("FrameUSecs"));
}

DWORD MAC ()
{
    // MAC analysis
    printf( "%04X%02X-%02X%04X", DS1,DS2>>8,DS2&0xFF,DS3);
    printf( "%04X%02X-%02X%04X", SS1,SS2>>8,SS2&0xFF,SS3);
}

//IPX packet Interpretation
DWORD IPX ()
{
    printf("IPX: ");
    printf( "0x%08X.0x%04X",SNet,SSocket);
    printf("=>");
    printf( "0x%08X.0x%04X :|:",DNet,DSocket);
}

 

Adding IPv4 protocol

Now we want add the IPv4 protocol. Let's examine the IPv4 header:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Version Header len. Type Of Service Total length
Identification Flags Fragment Offset
Next Protocol Time To Live Header Checksum
Source Address
Destination Address
Option Padding

Protocol definition PDF

If the 'Length' field in the MAC protocol is equal to 0x0800 then the next protocol can be IPv4 or IPv6. So we have to add a virtual protocol called IP4_6 that determines the next protocol by reading the field 'Version'.

In the MAC protocol we add a line that manages the call to the virtual protocol:

CASE (LEN_TYPE=2048) : IP4_6

Then we add the virtual protocol:

VIRTUAL PROTOCOL IP4_6
 BYTE VLEN
 {
  BITS VERSION (4,7)
  BITS HLEN (0,3)
 }
ENDPR
 SKIP: (-1)
 CASE (VERSION=4) : IP
 ELSE UNSUPPORTED

The SKIP instruction brings one byte back the point where the parser arrived to read the packet. So the byte containing the fields 'version' and 'header length' will be considered by the next protocol instructions. If we added also IPv6 we had to add the line:

 CASE (VERSION=6) : IP6

The IP protocol definition:

PROTOCOL IP
 BYTE VLEN
 {
  BITS VERSION (4,7)
  BITS HLEN (0,3)
 }
 BYTE TOS
 WORD TLEN
 WORD IDENTIFICATION
 WORD FFO
 {
  BITS FLAGS (12,15)
  BITS FRAGMENTOFFSET (0,11)
 }
 BYTE TTL
 BYTE NEXTPROTOCOL
 WORD HCHECKSUM
 DWORD SADDRESS
 DWORD DADDRESS
ENDPR
 SKIP: ((HLEN*4)-20)
 CASE ((NEXTPROTOCOL=6)&&(FRAGMENTOFFSET=0)) : TCP
 ELSE UNSUPPORTED


The instruction SKIP sets the 'reading sign' after the field 'Option' whose length is expressed by the field 'hlen'.

Protocol print definition DFF

DWORD IP ()
{
    //IP packet Interpretation
    if(Version!=4) return -1;
    title( "IPv4 Header");
    ResetLog(offsetof(vlen),offsetof(vlen)+1,1);
    printf( "Version = %u",Version);
    ResetLog(offsetof(vlen),offsetof(vlen)+1,1);
    printf( "Header length = %u bytes",HLEN);
    printf( "Type of service = %02Xh",TOS);
    ResetLog(offsetof(TOS),offsetof(TOS)+1,1);
    printf( " %3b. .... = priority %u",TOS>>5,TOS>>5);
    ResetLog(offsetof(TOS),offsetof(TOS)+1,1);

    if (TOS&0x10) printf( " ...1 .... = low delay");
    else printf( " ...0 .... = normal delay");
    ResetLog(offsetof(TOS),offsetof(TOS)+1,1);

    if (TOS & 0x08) printf( " .... 1... = high throughput");
    else printf( " .... 0... = normal throughput");
    ResetLog(offsetof(TOS),offsetof(TOS)+1,1);

    if(TOS & 0x04) printf( " .... .1.. = high reliability");
    else printf( " .... .0.. = normal reliability");
    ResetLog(offsetof(TOS),offsetof(TOS)+1,1);

    if(TOS & 0x02) printf( " .... ..1. = low monetary cost");
    else printf( " .... ..0. = normal monetary cost");

    printf( "Total length = %u bytes",TLen);
    printf( "Identification = %u", Identification);
    ResetLog(offsetof(Flags),offsetof(Flags)+1,1);
    printf( "Flags = %01Xh",Flags);
    ResetLog(offsetof(Flags),offsetof(Flags)+1,1);

    if(Flags&0x8) printf( " 1... .... = error: must be 0");
    else printf( " 0... .... = must be 0");
    ResetLog(offsetof(Flags),offsetof(Flags)+1,1);

    if(Flags&0x4) printf( " .1.. .... = do not fragment");
    else printf( " .0.. .... = may fragment");
    ResetLog(offsetof(Flags),offsetof(Flags)+1,1);

    if(Flags&0x2) printf( " ..1. .... = more fragment");
    else printf( " ..0. .... = last fragment");

    printf( "Fragment offset = %u bytes",FragmentOffset*8);
    printf( "Time to live = %u seconds/hops",TTL);
    printf( "Protocol = %u (%i)",NextProtocol,offsetof(NextProtocol));
    printf( "Header chechsum = %04Xh",HCHECKSUM);

    printf( "Source address = [%u.%u.%u.%u]", SAddress>>24&0xFF, SAddress>>16&0xFF,
                        SAddress>>8&0xFF,SAddress&0xFF);
    printf( "Destination address = [%u.%u.%u.%u]", DAddress>>24&0xFF, DAddress>>16&0xFF,
                        DAddress>>8&0xFF,DAddress&0xFF);
    ResetLog();

    if(HLEN>20) printf( "Options = %u bytes",HLEN-20);
    else printf( "No IP options");
}

ResetLog()

This function is used to modify the packet hexdump view (Analyzer's third panel). Each time Analyzer finds a printf() in the DFF file, it supposes that the user wants to print information about the next field defined into the PDF file. It follows that each printf() must coincide with a single field (multiple printf() for a single field lead to a wrong display in the third panel). By the way, Analyzer starts a new line in the packet details each time it finds a new printf().

ResetLog() is a function that can be used to change the way hexdump is highlightened. Function has three different forms:

 

Index packet print definition IFF

DWORD IP ()
{
    //IP packet Interpretation
    if(Version!=4) return -1;
    printf("IP: ");
    printf( "%u.%u.%u.%u", SAddress>>24&0xFF,SAddress>>16&0xFF,
                           SAddress>>8&0xFF,SAddress&0xFF);
    printf("=>");
    printf( "%u.%u.%u.%u", DAddress>>24&0xFF,DAddress>>16&0xFF,
                               DAddress>>8&0xFF,DAddress&0xFF);
    printf( " (%u) :|:", TLen);
}

 

Adding TCP protocol

TCP header:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Source Port Destination Port
Sequence Number
Acknowledgement Number
Data Offset Res Control Window
Checksum Urgent Pointer
Options Padding

Protocol definition PDF

In the IP definition we have added the line:

CASE ((NEXTPROTOCOL=6)&&(FRAGMENTOFFSET=0)) : TCP

Then we add the TCP protocol definition:

 PROTOCOL TCP
 WORD SPORT
 WORD DPORT
 DWORD SNUMBER
 DWORD ACKNUMBER
 BYTE W1
 {
  BITS RES (0,3)
  BITS DATAOFFSET (4,7)
 }
 BYTE CONTROL
 WORD WINDOW
 WORD CHECKSUM
 WORD URGENTPTR
ENDPR
 SKIP: ((DATAOFFSET*4)-20)
 ELSE DATA

The instruction SKIP sets the reading sign where the next protocols should start. Anyway we do not add any CASE instructions because we do not add protocols that follow TCP. So all the bytes following the TCP header are considered as data. In our definition TCP options are not supported.

Protocol print definition DFF

In the TCP definition function we notice these new instructions:

//TCP packet Interpretation
DWORD TCP ()
{
    DWORD headerLength;

    resetlog(offsetof(sport),offsetof(sport)+DataOffset*4);
    printf ("----- TCP Header -----");
    printf( "Source port = %u (%t)",SPort,offsetof(SPort));
    printf( "Destination port = %u (%t)",DPort,offsetof(DPort));
    printf( "Sequence number = %u" ,SNumber);
    printf( "Acknowledgement number = %u" ,AckNumber);
    CHECK(13);
    headerLength=DataOffset*4;
    ResetLog(offsetof(DataOffset),offsetof(DataOffset)+1,1);
    printf( "Header length = %u bytes",headerLength);
    printf( "Flags = %02Xh" ,Control );
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if(Control &0x20)
        printf( " ..1. .... = Urgent pointer");
    else
        printf( " ..0. .... = No urgent pointer");
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if (Control & 0x10)
        printf( " ...1 .... = Acknowledgement");
    else
        printf( " ...0 .... = No acknowledgement");
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if (Control  & 0x08)
        printf( " .... 1... = Push");
    else
        printf( " .... 0... = No push");
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if (Control  & 0x04)
        printf( " .... .1.. = Reset");
    else
        printf( " .... .0.. = No reset");
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if (Control  & 0x02)
        printf( " .... ..1. = SYN");
    else
        printf( " .... ..0. = No SYN");
    ResetLog(offsetof(Control),offsetof(Control)+1,1);
    if (Control  & 0x01)
        printf( " .... ...1 = FIN");
    else
        printf( " .... ...0 = No FIN");
    printf( "Window = %u",Window);
    printf( "Checksum = %04Xh" ,Checksum);
    printf( "Urgent pointer = %u",UrgentPtr);
    if (headerLength>20)
    {
      DWORD pos,tmp,tmp2;
      tmp2=headerLength-20;
      resetlog(offsetof(UrgentPtr)+2,offsetof(UrgentPtr)+2+tmp2);
      printf( "Options = %u bytes" ,tmp2);
      pos=GetVmVar("SizeInt")+20;
      check(pos);
      tmp=CONV16(pos);
      if (tmp==0x204)
      {
         printf( " Code = %X (MSS)" ,tmp);
         printf( " Required MSS: %u",conv16(pos+1));
         tmp2=tmp2-4;
    }
      if (tmp2>0)
        printf(" Other Options");
    }
    else
      printf( "No TCP options" );
}

Interestingly, DFF file is able to recognize some options, even if the DFF does not support them. This is clearly a dirty way of doing that. However, it works. 

Index packet print definition IFF

//TCP packet Interpretation
DWORD TCP ()
{
    printf("TCP: ");

    printf( "Port (%u => %u) ",SPort,Dport);
    printf( "Data (SN %u, ACK %u) ", SNumber,AckNumber);
}