Capture filters for network analyzers (tcpdump, Wireshark, Paketyzer)

  • Tutorial

1. Capture Filters


Traffic analyzers are a useful and effective tool in the life of a network administrator, they allow you to "see" what is actually transmitted on the network, which simplifies the diagnosis of various problems or the study of the principles of operation of certain protocols and technologies.
However, quite a lot of various data blocks are often transmitted on the network, and if you force to display everything that passes through the network interface, highlighting what is really necessary can be problematic.
To solve this problem, traffic analyzers have implemented filters that are divided into two types: capture filters and display filters. Today we will talk about the first type of filter - capture filters.
Capture filters is a type of filter that allows you to limit the capture of frames only to those that are necessary for analysis, thus reducing the load on the computing resources of the computer, as well as simplifying the process of traffic analysis.

2. Syntax of capture filters


The capture filter expression consists of a set of special primitives that are built from the so-called classifiers and object identifiers (addresses, names of network objects, port numbers).
Attention : all classifiers are case-sensitive and should be written only in small letters.

Let's deal with them in more detail.
Classifiers can be of the following varieties:
  • type - object type
    • host - host (the default type, if the type is not specified, it is assumed that this is host)
    • net - network
    • port - port


For example :
host 192.168.0.1 - traffic capture in which the address (sender or recipient) is IP 192.168.0.1
net 172.16.0.0/16 - traffic capture in which the address (sender or recipient) is IP from the network 172.16.0.0 / 16 (more precisely, it ranges from 172.16.0.0 to 172.16.255.255), while, since this is just a search filter for matching addresses, it doesn’t matter which mask is configured on the interface, and you should not be confused by the mask 172.16.0.0 / 16 is the network number, we absolutely do not know what mask is configured on the interface, and formally, such a host address is valid them.
port 80 - traffic capture in which there is data belonging to port 80 (udp or tcp)
10.0.0.1 - Traffic capture in which the address (sender or recipient) is IP 10.0.0.1, the host classifier is not specified, but it is assumed by default.

  • dir - direction relative to the object (direction)
    • src - the object is the sender
    • dst - the object is the receiver


For example :
src host 192.168.0.1 - traffic capture in which the source address (not the recipient) is IP 192.168.0.1
dst net 172.16.0.0/16 - traffic capture in which the destination address (not the sender) is IP from the network 172.16 .0.0 / 16 (more precisely, in the range from 172.16.0.0 to 172.16.255.255).

  • proto - interaction protocol
    • ether - the basic Ethernet network technology, usually indicates that the filter uses a hardware MAC address
    • ip - IPv4 protocol
    • ip6 - IPv6 protocol
    • arp - ARP protocol
    • tcp - TCP protocol
    • udp - UDP protocol
    • if no protocol is specified, then it is considered that all traffic compatible with the type of object should be captured


For example :
src ether host 00: 11: 22: 33: 44: 55 - traffic capture in which 00: 11: 22: 33: 44: 55 is used as the sender's MAC address.
ip icmp - capture ICMP packets.
tcp port 80 - traffic capture in which there is data belonging to TCP port 80

In addition to object identifiers and classifiers, filters can contain the keywords gateway , broadcast , multicast , less , greater, as well as arithmetic expressions.
For example :
ip multicast - capture ip packets containing addresses from class D.
less 1000 - capture frames whose size is less than 1000 bytes.

A bunch of conditions can occur using logical operations:
  • “And” - and (&&)
  • OR - or (||)
  • "NOT" - not (!) - inverse of the value

The priority of these operations is as follows:
  • inversion operation has the highest priority
  • then the logical "AND"
  • the lowest priority is the operation "OR".

As in ordinary mathematical expressions, priority can be changed using parentheses (), the actions in which are performed first.
For example :
net 192.168.0.0/24 and tcp port 21 - capture traffic belonging to the network (range) 192.168.0.0/24 (either the sender or the recipient) and transmit data via TCP and using port 21.
host 192.168.0.1 or host 192.168. 0.221 - capture of traffic belonging to either host 192.168.0.1 or host 192.168.0.221 (it doesn’t matter who the sender is, who the recipient is, and one of the two conditions is sufficient if at least one of these addresses is present in the frame)
host 192.168. 0.1 or host 192.168.0.2 and tcp port 22 - or capture any traffic belonging host 192.168.0.1 and tCP traffic or protocol Execu adhesive port 22 belonging to the host 192.168.0.2.
(host 192.168.0.1 or host 192.168.0.2) and tcp port 22- capture of TCP protocol traffic and using port 22 belonging to host 192.168.0.1 or host 192.168.0.2 (to either of them, or both at once).
(host 192.168.0.1 || host 192.168.0.1) && not tcp port 22 - capture any traffic other than TCP protocol traffic and using port 22 belonging to host 192.168.0.1 or to host 192.168.0.2 (either of them, or both).

If the filter has several identical repeating classifiers, then to reduce the record they can be omitted.
For example :
net 192.168.0.0/24 and (tcp port 21 or tcp port 20 or tcp port 25 or tcp port 80 or tcp port 110)
can be reduced to
net 192.168.0.0/24 and (tcp port 21 or 20 or 25 or 80 or 110)

Note : An
expression that excludes packets that have addresses 1.1.1.1 and 1.1.1.2:
not (host 1.1.1.1 and host 1.1.1.2)
can be abbreviated as:
not (host 1.1.1.1 and 1.1.1.2)
but not like:
not host 1.1.1.1 and 1.1.1.2 - in this case packets will be shown in which there is no first address and there is a second.
And not so
not (host 1.1.1.1 or 1.1.1.2) - in this case packets in which there is at least one of the indicated two addresses will be excluded.

A list of the basic primitives that can be used to write capture filters is shown in Table 2-1.

Table 2-1. List of basic primitives that can be used to write capture filters.
PrimitiveDescription
dst host ip_addressCapture frames in which the destination IPv4 / IPv6 header contains the specified host address
src host ip_addressCapture frames in which the IPv4 / IPv6 header contains the specified host address in the sender address field of the header
host ip_addressCapture frames in which the IPv4 / IPv6 header contains the specified host address in the sender or receiver address field of the header.
Equivalent to filter:
ether proto ip and host ip_address
ether dst mac_addressCapture frames in which the specified MAC address of the node contains in the address field of the recipient of the link layer header
ether src mac_addressCapture frames in which the specified MAC address of the node in the sender address field of the link layer header contains
ether host mac_addressCapture frames in which the specified MAC address of the node contains in the address field of the sender or receiver of the link layer header
dst net networkCapture frames in which the IPv4 / IPv6 header address field contains the specified address that belongs to the range of the specified class network
src net networkCapture frames in which the IPv4 / IPv6 header contains the specified address in the sender address field of the specified class network range
net networkSelects all IPv4 / IPv6 packets containing addresses from the specified network in the sender or recipient field
net network mask maskCapture frames in which the IPv4 / IPv6 header contains the specified address in the range of the specified network in the address or sender address field
net network / mask_lengthCapture frames in which the IPv4 / IPv6 header contains the specified address in the range of the specified network in the address or sender address field
dst port portCapture frames in which the UDP or TCP header destination port contains the specified port number
src port portCapture frames in which the UDP or TCP header port contains the specified port number
port portCapture frames in which the UDP or TCP header port contains the specified port number
less lengthCapture frames no larger than the specified value
greater lengthCapture frames whose size is not less than the specified value
ip proto protocolCapture frames that contain the identifier of the specified protocol in the “Protocol” field of the IPv4 header. In this case, you can specify not only the numerical values ​​of the protocols, but also their standard names (icmp, igmp, igrp, pim, ah, esp, vrrp, udp, tcp and others). However, it should be borne in mind that tcp, udp and icmp are also used as keywords, therefore, a backslash character ("\") should be added before these symbolic identifiers
ip6 proto protocolCapture frames that contain the identifier of the specified protocol in the “Protocol” field of the IPv4 header. In this case, you can specify not only the numerical values ​​of the protocols, but also their standard names (icmp6, igmp, igrp, pim, ah, esp, vrrp, udp, tcp and others). However, it should be noted that tcp, udp and icmp6 are also used as keywords, therefore, a backslash character ("\") should be preceded by these symbolic identifiers
ether broadcastCapture all broadcast Ethernet frames. Ether keyword may be omitted
ip broadcastCapture frames containing broadcast addresses in the IPv4 packet header. In this case, to determine whether the address is broadcast, subnet masks are used for the interface that is used to capture packets. It also captures packets sent to a limited broadcast address
ether multicastCapture all Ethernet multicast frames. Ether keyword may be omitted
ip multicastCapture frames containing multicast addresses in the IPv4 packet header
ip6 multicastCapture frames containing multicast addresses in the IPv6 packet header
ether proto protocol_typeCapture Ethernet frames with the specified protocol type. The protocol can be specified by number or name (ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, netbeui)
ip, ip6, arp, rarp, atalk, aarp, decnet, iso, stp, ipx, netbeui, tcp, udp, icmpCapture frames transmitting data of the specified protocol. Used as abbreviation for:
ether proto protocol
vlan [vlan_id]Capture frames in accordance with IEEE 802.1Q. If vlan_id is specified, only frames belonging to the specified VLAN are captured


3. Advanced examples of capture filters


In addition to the simple indication of addresses and protocols in the capture filters, you can use more complex constructions that allow for more subtle header analysis.
For this, expressions returning a logical value of the following format are used:
expression operation expression

In which expression can be constants, the results of arithmetic (+, -, *, /) or binary bitwise operations (& - “AND”, | - “OR”, << - shift to the left, >> - shift to the right), the operator is long offset , data or header field fields. Symbols “>” (more), “<” (less), “> =” (more equal), “<=” (less than equal), “=” (equal), “! =” Can be used as an operation (not equal). Thus, it is possible to check for coincidence or non-coincidence of certain fields or bytes of a frame with the necessary values, compare different header fields with each other, and also perform some arithmetic and logical operations on them and compare the results of these operations with certain values.
5 = 3 + 1 ”, where“ 5 ”and“ 3 + 1 ”are expression, and“ = ”is the operation. As a result of calculating this string, a boolean value will be returned, in this case false .

To obtain data or frame headers, the proto [ offset : size ] primitive is used .
Note : the square brackets in this case are a syntax element, not a sign of an optional field.

The proto parameter contains the name of the protocol, from the header of which you need to select certain data (ether, fddi, tr, wlan, ppp, slip, link, ip, arp, rarp, tcp, udp, icmp, ip6 and others).
The offset parameter indicates the offset in bytes relative to the beginning of the header of the specified protocol, the numbering of bytes starts from zero: ip [0] - the first byte from the beginning of the IP packet, tcp [1] - the second byte from the beginning of the TCP segment, ether [3] - the fourth byte from the start of an Ethernet frame.
The size parameter indicates the number of bytes to be taken, starting from the byte specified in the offset , the size fieldis optional, and if it is absent, then it is considered that it is necessary to take 1 byte: ip [2: 2] - the third and fourth bytes from the beginning of the IP packet, tcp [4] - the fifth byte from the beginning of the TCP segment, ether [6-6 ] - bytes from the seventh to the twelfth, from the beginning of the Ethernet frame.
If you set a negative value in the offset field , then the bytes of the previous header will be selected that go to the protocol header specified in the proto parameter . But at the same time, the presence of the protocol header specified in the proto primitive will be required in the frame. Thus, the filters ether [11] = 0x37 (take the 12th byte of the Ethernet frame and compare it with the value 0x37) and ip [-3] = 0x37(take the 3rd byte from the end of the header preceding the IP header and compare it with the value 0x37) are not identical. In the first, all frames in which the sender's MAC address ends with 37 will be skipped, and in the second, IP will also be required, and frames not containing the IP protocol, for example, ARP frames, will not be captured.
For example :
The expressions ip [1: 1] and ip [1] will produce the same result - the second byte of the IPv4 header will be selected.
The expression tcp [8: 2] will select the ninth and tenth bytes (Source Port field) of the TCP header.
The expression ip [-3] = 0x37 will select all IPv4 packets whose sender MAC address ends with “0x37”.

Keep in mind that when choosing data using the proto [ offset : size ] construct for the TCP and UDP protocols, fragmentation of IP packets is taken into account. As a result, tcp [0] will always mean the first byte of the TCP header, and will never lead to the selection of the first byte of packet data that transfers not the first fragment from the fragment chain.
For some protocols, certain fields and offset values ​​can be specified not only by numbers, but also by names. For example, for the ICMP protocol, the icmptype parameter is supported , which can take the values icmp-echoreply , icmp-unreach , icmp-sourcequench , icmp-redirect, icmp-echo , icmp-routeradvert , icmp-routersolicit , icmp-timxceed , icmp-paramprob , icmp-tstamp , icmp-tstam-preply , icmp-ireq , icmp-ireqreply , icmp-maskreq , icmp-maskreply . To analyze TCP flags, you can use the tcpflags parameter identifiers tcp-fin , tcp-syn , tcp-rst , tcp-push , tcp-ack and tcp-urg .
For example :
The expression tcp [tcpflags] & (tcp-syn | tcp-fin)! = 0 will select all frames containing TCP segments in which the session opens or ends.
The expression i cmp [icmptype]! = Icmp-echo and icmp [icmptype]! = Icmp-echoreply selects all frames containing the ICMP protocol, except for echo requests and echo responses.

There may be situations in which it is necessary to analyze only part of the bits of a specific byte. To solve these problems, the bit operation "AND" (&) is used. With it, you can save only certain bits of a byte, and the rest can be reset.
For example, we need to select only those frames that are transmitted at the channel level by broadcast or multicast frames. We know that you can determine the type of MAC address by its high byte:
Type of addressHigh byte value in the 16th systemHigh byte value in 2nd system
Directional \ Unicast0000000000
Group \ Multicast0100000001
Administratively assigned \ admin ID0100000010
Broadcast \ BroadcastFf11111111

Based on this information, we can conclude that in broadcast or multicast addresses the low-order bit of the high byte of the address is one, and in the rest it is zero. If we take the high byte of the address, zero all its bits except the lowest one, and the byte value becomes equal to one, then this address was either broadcast or multicast, if the byte value becomes zero, then this address was either directed or administrative given. As a result, to perform this check, the following expression must be used: ether [0] & 1 = 1 , where ether [0] - receives the value of the first byte of the Ethernet header, and & 1 - the logical “And” bit operation, zeroing all bits of this byte, except the low , " = 1»- check the result for a match with a unit.
Let us examine one more example in more detail.
We need to get the contents of the Type Of Service (ToS) field of the IPv4 header. To do this, referring to RFC-791, we will see that this field is a single-byte field, and the second byte of the header:
3.1. Internet Header Format
  A summary of the contents of the internet header follows:
    0 1 2 3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Version | IHL | Type of Service | Total length |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Identification | Flags | Fragment Offset |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Time to Live | Protocol | Header Checksum |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Source Address |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Destination Address |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
   | Options | Padding |
   + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +

In order to get its value we need to use the following primitive:
ip [1: 1] - get one byte of the IP header starting from byte number 1 (byte numbering starts from zero).
Now we can build filters based on the contents of this field.
If we want all frames containing the IPv4 header to be displayed in which the ToS field is zero, we need to write the following: ip [1: 1] = 0 .
If we want all frames containing the IPv4 header to be displayed, in which the ToS field is not zero, we need to write the following: ip [1: 1]! = 0 .
But you can go further, according to RFC-791, the ToS field is a composite field and has the following structure:
         0 1 2 3 4 5 6 7
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
      | | | | | | |
      | PRECEDENCE | D | T | R | 0 | 0 |
      | | | | | | |
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
      Bits 0-2: Precedence.
      Bit 3: 0 = Normal Delay, 1 = Low Delay.
      Bits 4: 0 = Normal Throughput, 1 = High Throughput.
      Bits 5: 0 = Normal Relibility, 1 = High Relibility.
      Bit 6-7: Reserved for Future Use.

The first three bits are preference, the fourth describes latency requirements, the fifth describes bandwidth requirements, the sixth describes link reliability requirements, the seventh and eighth are reserved for future use.
If we turn to the newer standards (RFC1349), the value of the seventh bit has already been determined - the price requirements are “Cost” (monetary equivalent).
And now, let's say we want to determine if there are frames on the network in which the seventh bit of the ToS field is set in the IPv4 header. How to do it? To solve this problem, we need to remember (or learn: D) the binary system of calculus. In a byte, each bit has its own weight, which starts with one, and increases, from right to left, each time multiplied by two.
         0 1 2 3 4 5 6 7
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
      | | | | | | |
      | PRECEDENCE | D | T | R | C | 0 |
      | 0 0 0 | 0 | 0 | 0 | 1 | 0 |
      | | | | | | |
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
        128 64 32 16 8 4 2 1

It turns out that the weight of the bit of interest to us is 2.
What if we compare the value of the ToS field with a two?
ip [1: 1] = 2
Will we get an answer to the question, is there a bit of interest to us in this header? On the one hand, yes, but on the other hand, no.
For example, if we have in the ToS field, in addition to the “Cost” bit, other bits set to one? Let's say it will be the bit responsible for the bandwidth requirements - “Throughput”.
         0 1 2 3 4 5 6 7
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
      | | | | | | |
      | PRECEDENCE | D | T | R | C | 0 |
      | 0 0 0 | 0 | 1 | 0 | 1 | 0 |
      | | | | | | |
      + ----- + ----- + ----- + ----- + ----- + ----- + ----- + ----- +
        128 64 32 16 8 4 2 1

As a result, the value of this byte will no longer be 2, but 10, and a simple comparison cannot give an answer to the question whether a certain bit is set in the field of interest to us.
What prevents us from getting the answer we are interested in? We are disturbed by the value of others, possibly also set to a unit of bits. Accordingly, we must get rid of them. To solve this problem, we use the operation of bitwise logical "AND" (sometimes called logical multiplication), indicated by the symbol " &". As you know, in the logical operation “AND”, the output will only be one when both the first operand and the second are equal to one. Accordingly, if we perform bitwise multiplication of the value of the ToS field by a special mask in which only the bit that is at the position of the bit of interest in the ToS field will be set to unity, we will exclude all other bits from the result:
ToS field: 00001010 = 10
Mask: 00000010 = 2
Result: 00000010 = 2


Whatever the value of the remaining bits, when applying this mask, the result will only get the value of the field of interest to us. Even if we set all the bits to one, this will not affect the result:
ToS field: 11111111 = 255
Mask: 00000010 = 2
Result: 00000010 = 2

And only if the bit of interest to us is equal to zero, as a result of masking, there will also be zero.
ToS field: 11111101 = 253
Mask: 00000010 = 1
Result: 00000000 = 0

Thus, if the bit of interest to us is equal to one, as a result of masking we will get the weight of this bit, if it is equal to zero, then we will get zero.
Based on this, to solve this problem, we need to apply the following filter:
ip [1: 1] & 2 = 2

It will take the value of the second byte, apply a mask to it that “cuts out” the value of a certain bit and compare the result with the weight of this bit.

We can give another example based on the analysis of the Type Of Service field of the IP header: we need to see all the frames in which the Precedence bits (preference) are not equal to zero in the IPv4 header in the ToS field. To do this, apply a mask into which we select the bits that are responsible for Precedence:
ToS field: 10111101 = 189
Mask: 11100000 = 224
Result: 10100000 = 160

The result is not equal to zero, and this indicates that the Precedence field is also not equal to zero.

ToS field: 00011111 = 31
Mask: 11100000 = 224
Result: 00000000 = 0

The result is zero, and this indicates that the Precedence field is also zero.

As a result, checking for a non-zero value of the ToS field in the IPv4 header will look like this:
ip [1: 1] & 224! = 0
or the same thing, but using the hexadecimal option:
ip [1: 1] & 0xe0! = 0

Consider example with a different protocol. Take the TCP protocol.
For example, we need to capture all frames that transmit TCP segments with options. In order to understand what you need to look for and where we turn to RFC-793.
  TCP Header Format
    0 1 2 3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

To determine if there are options in the segment, the “Data Offset” field is used, it shows the length of the header in four-byte words. The minimum TCP segment header length is 20 bytes, which is 5 four-byte words. Accordingly, if there are options in the TCP segment header, then the value of this field will be greater than 5.
In order to get the value of this field, you must use the tcp primitive [12: 1] . However, given the fact that the minimum piece that we can take is one byte, and we need only 4 bits, we have to think a bit.
Applying the tcp primitive [12: 1] we got the following header piece:
   + - + - + - + - + - + - + - + -
   | Data |           
   | Offset | Reserved  
   | |           
   + - + - + - + - + - + - + - + -

If the “Data Offset” field were in the lower part of the byte, then the number “5” in binary representation would look like this:
        128 64 32 16 8 4 2 1
         0 0 0 0 0 1 0 1 = 5

But the bits of interest to us are not in the left, younger, but in the right, senior part of it, therefore, to get the decimal equivalent, we transfer them to the right side of the byte:
        128 64 32 16 8 4 2 1
          0 1 0 1 0 0 0 0 = 80 (0x50 in hexadecimal)

To select the most significant bits, you need to mask:
Data Offset field: 01010000 = 80
Mask: 11110000 = 240
Result: 01010000 = 80

If there are still options in the header, then the “Data Offset” value will be more than 5. For example, if there is one eight-byte option in the header, the value of this field will be 7 (5 four-byte words of the fixed part of the header, and 2 four-byte option words):
        128 64 32 16 8 4 2 1
         0 0 0 0 0 1 1 1 = 7

Transferring the corresponding bits to the upper part we get:
        128 64 32 16 8 4 2 1
          0 1 1 1 0 0 0 0 = 112 (0x70 in hexadecimal)

Highlight the high bits by masking:
Data Offset field: 01110000 = 112
Mask: 11110000 = 240
Result: 01110000 = 112

Thus, it turns out that if the result is a value greater than 80, then there are options in the TCP header. In principle, there was no need to apply a mask here, since the extra bits are still reserved, and should always be zero, but you never know what can change, and in order not to rewrite the filter, if the standard suddenly changes, we better cut them off with a mask.
The resulting filter, which shows those TCP segments in which the length of the TCP header is more than 5 four-byte words, turned out to be the following:
tcp [12: 1] & 240! = 80
or
tcp [12: 1] & 240> 80
or
tcp [12: 1 ] & 0xf0> 80
Also, let's consider the possibility of working with TCP flags. They can be selected in the same way using the mask, but you can also use the symbolic classifiers that were listed above.
For example, in order to capture frames containing segments with the SYN or FIN flags, you need to write the following filter:
tcp [tcpflags] & (tcp-syn | tcp-fin)! = 0
I think it is quite readable and does not require any special explanation.
The implementation of such a task through bits and masks would lead to such a filter format:
tcp [13: 1] & 2! = 0 or tcp [13: 1] & 1! = 0
To consolidate the understanding of the topic, try to figure out how this one filter option will work.
Например:
Выражение ether[0]&1 != 0 выберет все широковещательные кадры.
Выражение ether[0] & 1 = 0 and ip [16]>= 244 выберет все широковещательные или групповые IP пакеты, в которых на канальном уровне не используется широковещательный или групповой MAC адрес.
Выражение ip[0]&0xf = 5 выберет все IP пакеты, в которых нет опций.
Выражение ip[6:2]&0x1fff = 0 выберет все не фрагментированные IP пакеты, и первые фрагменты фрагментированных пакетов.
Выражение ip[-3]&0xff = 0x37 выберет все IP пакеты, MAC адрес отправителя которых заканчивается на «0x37».

Another interesting set of bit operations is bit shift operations. These operations are indicated by the symbols “pair of arrows”: “<<” - shift to the left and “>>” - shift to the right.
How do they work?
Take an arbitrary byte, for simplicity we take a unit, and write its value in the binary system:
        128 64 32 16 8 4 2 1
          0 0 0 0 0 0 0 1 = 1

Now we’ll perform a bit shift operation to the left, shifting the values ​​of all bits by one position, and putting zero in the least freed bit:
        128 64 32 16 8 4 2 1
         0 0 0 0 0 0 1 <<

        128 64 32 16 8 4 2 1
         0 0 0 0 0 0 1 0 = 2

As a result, the byte value became equal to two, that is, doubled. And once again apply this operation:
        128 64 32 16 8 4 2 1
         0 0 0 0 0 1 0 <<

        128 64 32 16 8 4 2 1
         0 0 0 0 0 1 0 0 = 4

As a result, the byte value became equal to four, that is, it doubled again. Thus, we can conclude that the operation of bit shifting to the left is equivalent to multiplying the value of the byte by two (since we work with the binary system).
Let's check the validity of this rule on a more complex number, for example, 100. We write it in binary form:
        128 64 32 16 8 4 2 1
          0 1 1 0 0 1 0 0 = 100

And now we’ll perform a left shift operation:
        128 64 32 16 8 4 2 1
         1 1 0 0 1 0 0 <<

        128 64 32 16 8 4 2 1
         1 1 0 0 1 0 0 0 = 200

As a result, the byte value became equal to 200 - doubled.
Accordingly, we can immediately conclude that the bit shift to the right is equivalent to dividing the number by two.
For example, the number 240:
        128 64 32 16 8 4 2 1
          1 1 1 1 0 0 0 0 = 240

Let's perform a shift operation to the right:
        128 64 32 16 8 4 2 1
         >> 1 1 1 1 0 0 0

        128 64 32 16 8 4 2 1
         0 1 1 1 1 0 0 0 = 120

The byte value became equal to 120 - decreased by half.
How can we use this operation? Let's remember that the IHL (Internet Header Length) field of the IP header indicates the length of the header not in bytes, but in four-byte words, and in order to check whether the packet contains options, we used the following operation:
ip [0] & 0xf = 5
That is, they were compared not with the real value, but with the value divided into four (20 bytes are 5 four-byte words). If for some reason it is more convenient to work with the length of the header in bytes (for example, if this value must subsequently be subtracted from the total length of the packet), then it must be multiplied by 4. In order to multiply the number by 4, it must be doubled by two , that is, perform a bit left shift operation twice, and then compare it with the required long IP header in bytes:
ip [0] << 2 = 20

Well, of course, all this can be combined into composite rule sets:
(icmp [icmptype]! = icmp-echo and icmp [icmptype]! = icmp-echoreply) or (udp and udp port not 67 and ip [16] <224) or (tcp [0: 2] <1024 and tcp [2: 2] <1024)
With this filter, the program will only capture frames that fit one of three descriptions:
  • Contain ICMP messages except echo and echoreply (used by the ping utility)
  • UDP datagrams are transmitted, except for those that use port 67 as the sender or receiver port, and except for those that are transmitted to multicast addresses and to a limited broadcast address
  • Transmit TCP segments in which both the sender port and the receiver port are in the "Well-known ports" range


4. Self-examination task: D


To consolidate your work with complex capture filters, try to understand what this filter describes and how:
tcp port 80 and (ip [2: 2] - ip [0] & 0xf << 2 - tcp [12] & 0xf0 >> 2! = 0 )
Note :
This is one of the standard examples, and if necessary, you can easily check yourself using the Internet search, but still try to make an effort and deal with it yourself.

Have a nice sniff)

Only registered users can participate in the survey. Please come in.

Which traffic analyzer do you use most often?

  • 30.8% tcpdump 302
  • 65.1% Wireshark 638
  • 0% WinDump 0
  • 1.3% Network Monitor 13
  • 0.4% Ethereal 4
  • 0.3% Ntop 3
  • 0.1% Paketyzer 1
  • 1.9% other 19

Кто Вы, пользователи сетевых анализаторов?

  • 45.5%Я Администратор, и я использую сетевые анализаторы164
  • 5.2%Я Администратор, и я не использую сетевые анализаторы19
  • 13.3%Я Сетевой инженер (Дизайнер сети), и я использую сетевые анализаторы48
  • 1.1%Я Сетевой инженер (Дизайнер сети), и я не использую сетевые анализаторы4
  • 24.4%Я Программист, и я использую сетевые анализаторы88
  • 4.7%Я Программист, и я не использую сетевые анализаторы17
  • 5.2%Я Аудитор (Служба безопасности), и я использую сетевые анализаторы19
  • 0.2% I am an Auditor (Security Service), and I do not use network analyzers 1

Also popular now: