Network Protocol Analyzer User Manual
Using the Protocol Analyzer
Traffic flow analysis
The SoftPerfect Network Protocol Analyzer uses filters to include or exclude network packets. Most of the filters can be either inclusive or exclusive. In other words, they either accept or reject packets based on the criteria you have selected. If a filter is enabled, any packets that do not match the conditions set in that filter are discarded. This enables you to focus your analysis on the packets you are interested in. To apply a filter, choose Filters - Filter Settings in the main menu. When you have created a filter using this settings, you can save it for further use by selecting Filters - Save Filter in the main menu.
This tool filters packets based on a selected hardware mode:
- Promiscuous mode receives all packets passing through the the network interface card.
- Owner All mode receives only the packets intended for, or sent from, a specified network interface card. Many wireless network cards require this option instead of promiscuous mode.
- Owner Received mode receives only the packets intended for the selected network interface card.
- Broadcast mode accepts only broadcast packets.
You can use the protocol filter to include or exclude packets based on the protocol:
MAC address and IP address filters
Enter the addresses you want to filter the traffic between. All traffic destined for addresses outside the specified address range will be either excluded or included:
You can select one or more ports by entering numeric values or selecting from a predefined list of port labels. The packets with the port address matching your list will be included or excluded.
Enter one or more items into this filter. It operation depends on the filter mode:
- Discards packets with contents matching any list item.
- Discards packets with contents matching all list items.
Advanced filter and scripting
The program supports advanced filters based on a scripting language similar to the well-known assemblers like MASM or TASM, and allows to use Berkeley Packet Filter (BPF) machine commands for BPF filters writing. BPF assembler can use labels in conditional and unconditional jump commands, set constants, and constant definitions. Each BPF assembler instruction must be placed in a separate line:
Identifiers may be used in declarations of label names in conditional and unconditional jumps, and for declarations of constant expressions names. An identifier denotes a sequence of one or more letters, digits, and underscores ‘ _ ’, no longer than 32 symbols, starting with a letter.
A BPF assembler expression denotes a simple arithmetic expression, that consists of digits, identifiers, predefined constant expressions, symbols ‘ + ’, ‘ - ’, ‘ * ’, ‘ / ’, and brackets ‘ ( ’ and ‘ ) ’.
Named constant definition directive is set as
#define <identifier> <expression>
This directive allows to set a symbolic name for a constant expression. A named constant may be used only after its definition with the #define directive.
Labels may be set as
To declare a label in the program, type its name and add a colon ‘ : ’ at the end. A label can be declared on a separate line or before any other instruction. Use labels to define instructions on which you wish to jump to by a conditional or unconditional jump command. Backward jumps are not allowed.
A – accumulator, X – index register, P[...] – the packet data, and M[...] – the scratch memory store.
- P[i:n] returns the data at byte offset i in the packet, interpreted as a word (n=4), unsigned half-word (n=2), or unsigned byte (n=1).
- M[i] returns the i-th word in the scratch memory store, which is only addressed in word units. The memory store is indexed from 0 to 15.
- k, jt (jump if true), and jf (jump if false) are the corresponding fields in the instruction definition.
- #pktlen is a pseudo-variable containing the length of the packet.
LD copies a value into the accumulator. The type of the source operand is specified by an “addressing mode” and can be a constant, packet data at a fixed offset, packet data at a variable offset, the packet length, or a word in the scratch memory store.
|ld P[k:4]||A <- P[k:4]|
|ld P[k:2]||A <- P[k:2]|
|ld P[k:1] or ld P[k]||A <- P[k:1]|
|ld P[X+k:4]||A <- P[X+k:4]|
|ld P[X+k:2]||A <- P[X+k:2]|
|ld P[X+k:1] or ld P[X+k]||A <- P[X+k:1]|
|ld #pktlen||A <- packet length|
|ld k||A <- k|
|ld M[k]||A <- M[k]|
LDX loads a value into the index register.
|ldx k||X <- k|
|lldx M[k]||X <- M[k]|
|ldx #pktlen||X <- packet length|
|ldxm P[k:1] or ldxm P[k]||X <- 4*(P[k:1] & 0xf)|
ST stores the accumulator into the scratch memory.
|st M[k]||M[k] <- A|
STX stores the index register in the scratch memory store.
|stx M[k]||M[k] <- X|
ALU set. The ALU instructions perform operations between the accumulator and index register or constant, and store the result back in the accumulator.
|add k||A <- A + k|
|sub k||A <- A – k|
|mul k||A <- A * k|
|div k||A <- A / k|
|and k||A <- A & k|
|or k||A <- A | k|
|lsh k||A <- A << k|
|rsh k||A <- A >> k|
|add X||A <- A + X|
|sub X||A <- A – X|
|mul X||A <- A * X|
|div X||A <- A / X|
|and X||A <- A & X|
|or X||A <- A | X|
|lsh X||A <- A << X|
|rsh X||A <- A >> X|
|neg||A <- !A|
JUMP set. The jump instructions alter the program flow. Conditional jumps compare the accumulator against a constant or index register. If the result is true (or non-zero), the true branch is taken, otherwise the false branch is taken. Jump offsets are encoded in 8 bits, so the longest jump is 256 instructions forward. However, unconditional jump always uses the 32 bit k field as the offset, allowing longer jumps. All conditionals use unsigned jump offsets. JT (Jump if True) and JF (Jump if False) values are a number or expression with the result value from 0 to 255. This value also may contain a label of a command we want to jump to.
|jmp k||pc += k|
|jg k, JT, JF||pc += (A > k) ? JT : JF|
|jge k, JT, JF||pc += (A >= k) ? JT : JF|
|jeq k, JT, JF||pc += (A == k) ? JT : JF|
|jset k, JT, JF||pc += (A & k) ? JT : JF|
|jg X, JT, JF||pc += (A > X) ? JT : JF|
|jge X, JT, JF||pc += (A >= X) ? JT : JF|
|jeq X, JT, JF||pc += (A == X) ? JT : JF|
|jset X, JT, JF||pc += (A & X) ? JT : JF|
RET terminates the filter program. A return value of zero indicates that the packet should be ignored, otherwise accepted. The return value is either a constant or accumulator.
|ret A||accept A bytes|
|ret k||accept k bytes|
TAX, TXA copies the index register to the accumulator or vice versa.
|tax||X <- A|
|txa||A <- X|