Wireshark Display Filters for DFIR: From Field-Level Filtering to Defensible Evidence Export

 


Wireshark and tcpdump employ different filtering models, and the distinction matters when reducing and examining network evidence. Wireshark display filters operate on protocol fields exposed by its dissection engine, allowing examiners to filter on decoded fields such as http.request.method, smb2.cmd, and tls.handshake.extensions_server_name. Depending on the protocol and reassembly settings, Wireshark can also expose fields derived from reassembled packets and application-layer data. Because filtering depends on protocol dissection, results may vary with Wireshark versions, enabled heuristic dissectors, protocol preferences, TCP reassembly settings, and port-to-protocol assignments. Examiners should therefore document the Wireshark version and relevant configuration settings in their examination notes.


tcpdump, by contrast, uses Berkeley Packet Filter (BPF) expressions, typically compiled by libpcap and evaluated against packet data. Its filtering language provides protocol-specific primitives for common link-layer, network-layer, and transport-layer conditions, together with arithmetic and bitwise operations for examining packet bytes at specified offsets. However, it does not provide the rich application-layer field access available through Wireshark's dissection engine. Filtering on application-layer fields may therefore require explicit byte-offset and bitmask expressions, where feasible. Conventional libpcap capture filters also lack the protocol reassembly and application-layer dissection capabilities available in Wireshark. The advantage of BPF filtering is that it can reduce the volume of traffic retained during acquisition or when extracting packets from an existing capture, without requiring the full protocol dissection performed during subsequent analysis. BPF filtering is not exclusive to tcpdump: Wireshark capture filters use the same libpcap filter syntax, although they are distinct from Wireshark display filters.


A sound forensic workflow is to preserve the original capture, calculate and record its cryptographic hash, and create a working subset using a documented capture-filter expression where appropriate. Record the exact filter expression, command-line arguments, tool versions, and relevant acquisition details. Calculate a hash for the resulting derivative and maintain the relationship between the original and derived files in the examination record. Finally, conduct a detailed protocol-level examination using Wireshark display filters while retaining the original capture for validation and further analysis. A competent network forensic examiner should understand both filtering languages, their underlying matching mechanisms, and the limitations each introduces when identifying, reducing, and interpreting network evidence.


Wireshark display filters select packets for presentation based on protocol fields exposed by its dissection engine. They do not modify the underlying capture file; they determine which packets are displayed, leaving the original evidence unchanged while allowing an examiner to isolate packets of interest within a large dataset. Display filter syntax is distinct from BPF, and Wireshark supports its use through filter-bar autocomplete, saved filter buttons, and the "Apply as Filter" option available when selecting a protocol field. Because display-filter evaluation depends on protocol dissection, results can vary across Wireshark versions, enabled heuristic dissectors, protocol preferences, reassembly settings, and port-to-protocol assignments. Examiners should therefore document the Wireshark version and any relevant non-default preferences.


BPF expressions, by contrast, are evaluated against packet data without Wireshark-style protocol dissection. They provide protocol-specific primitives for common link-, network-, and transport-layer filtering, alongside arithmetic and bitwise operations for inspecting packet bytes at specified offsets. Although less expressive for application-layer analysis, capture filtering is typically more efficient for initial packet selection and reduction of large captures, particularly when the target field can be reliably located. However, manually constructed offset-based expressions can be affected by variable header lengths and encapsulation, including IP options, TCP options, IPv6 extension headers, and VLAN tags. Consequently, an empty result from an offset-dependent BPF filter should be validated against the original capture rather than treated as proof that the targeted traffic or field is absent.


Wireshark’s protocol dissectors decode captured bytes according to protocol specifications, assigning values to named, typed fields. For a DNS response, the dissector parses each resource record, resolves name compression pointers, and exposes components such as the owner name, record type, TTL, and resource data (rdata) as individually addressable fields. Display filters operate on this decoded protocol-field representation, allowing an examiner to select packets by field value (for example, dns.qry.name or dns.a) rather than by byte position. This is generally a more reliable approach to locating application-layer content than manually constructed byte-offset filters, provided that protocol identification and dissection are successful. Non-standard port assignments, tunneled or encapsulated traffic, truncated captures, missing TCP segments, and malformed packets can all result in incomplete or incorrect dissections. Out-of-order TCP segments can also affect higher-layer decoding when the necessary reassembly preferences are not enabled.


Examiners should consider Wireshark's Expert Information and malformed-packet indicators as part of their assessment, verify critical findings against the underlying packet bytes, and document the Wireshark version and relevant dissector-related preferences, including Decode As mappings, enabled heuristic dissectors, and TCP reassembly settings.


By contrast, conventional BPF capture-filter expressions evaluate packet bytes using protocol-specific primitives and byte-level operations rather than performing Wireshark-style application-layer dissection. They cannot resolve application-level constructs such as DNS name compression or reconstruct application data spanning multiple TCP segments. Consequently, BPF is typically more efficient for initial packet selection and capture reduction, while Wireshark display filters are better suited to detailed protocol-level examination.


Wireshark Display Filter Format

Wireshark display filters take several forms. The simplest tests for the presence of a protocol or field: the filter dns selects packets in which Wireshark identified a DNS layer, while ftp.response selects packets containing fields associated with FTP server responses. Because the dissector determines the match, results reflect Wireshark's protocol interpretation rather than necessarily establishing what the communicating endpoints intended.


Some fields are not explicitly present in the captured packet bytes but are generated by Wireshark during analysis. These include reassembly results, TCP analysis information, expert information, and checksum validation results. For example, ip.fragment.overlap identifies overlapping IPv4 fragments detected during reassembly, while udp.checksum.bad identifies UDP packets whose checksums fail validation. Although display filters cannot independently recompute checksums or compare the contents of different packets, they can evaluate these dissector-generated fields and compare multiple fields within an individual packet. The availability of these findings depends on relevant protocol preferences. IP reassembly must be enabled for fragment-related findings, while UDP checksum validation must be enabled for udp.checksum.bad to be populated. Examiners should also account for version-dependent preference defaults when interpreting these fields. Checksum findings require particular care. On traffic captured at the originating host, checksum offloading can produce apparently invalid checksums because the capture may occur before the network interface completes checksum calculation. Such findings should not automatically be interpreted as evidence of packet manipulation or corruption.


Another common display-filter form is field, operator, and value. For example, ip.src == 192.168.11.65 selects packets with that source address, while ipv6.fragment.offset > 0 selects non-initial IPv6 fragments. Examiners should record the Wireshark version, relevant protocol preferences, and reassembly and checksum-validation settings when documenting findings derived from these filters.


Relational operators

OperatorWord formMeaningExaminer’s note
==eq, any_eqEqualFor fields occurring more than once in a packet, true if any instance matches
!=ne, all_neNot equal3.6+: equivalent to !(a == b), so true only if no instance matches. Pre-4.0: true if any instance differed, so ip.addr != x matched nearly every packet
===all_eqEqual, all instancesEvery occurrence of the field must match
!==any_neNot equal, any instanceRestores the old pre-4.0 != behavior. Written ~= in 4.0 and deprecated afterward, so check your release
> <gt ltGreater than, less thanNumeric and ordered types only
>= <=ge leGreater than or equal, less than or equalSame


String, byte, and pattern operators

OperatorMeaningExaminer’s note
containsLiteral substring or byte-sequence matchNo wildcards or regex. Works on strings, byte fields, and frame, e.g. frame contains "cmd.exe" or frame contains 4d:5a:90
matches, ~PCRE regular expressionCase sensitivity has changed across versions, so use (?i) explicitly when you need case-insensitive matching


Both operators act on dissected and reassembled data. A string split across TCP segments will not match with reassembly disabled, so a negative result is not proof of absence.


Set, range, and bitwise operators

OperatorMeaningExample
inMembership in a set or rangetcp.port in {80 443 8080}, ip.ttl in {1..5}
&, bitwise_andBitwise AND, true if the result is non-zerotcp.flags & 0x02 isolates SYN regardless of other flags


Logical operators and grouping

OperatorWord formMeaningExaminer’s note
&&andBoth conditions true
||orEither condition true
^^xorExactly one condition true
!notNegationA bare !field tests for the field’s absence. Write !(ip.addr == x) to exclude a value
( )GroupingDo not rely on implicit precedence in documented filters. Parenthesize


Arithmetic and functions (4.0+)

ElementMeaning
+ - * / %Arithmetic on numeric fields, e.g. frame.len - tcp.len > 100
len(), count(), lower(), upper(), string()Field and string functions. Verify the exact set against your version’s wireshark-filter(4) man page
field[offset:length]Slice a field or the frame at a byte offset
field (bare)Existence test: true if the field is present in the dissected packet


Wireshark display filters support relational operators (==, !=, >, <, >=, <=), string and byte operators (contains, matches), and logical operators (&&, ||, !, with the word forms and, or, and not). Relational operators behave predictably on single-valued fields, but examiners should understand how multiple field occurrences are evaluated. Fields such as ip.addr can occur more than once in a packet, particularly in encapsulated traffic containing multiple IP headers. In Wireshark 3.6 and later, != requires all occurrences of a field to differ from the specified value, whereas Wireshark 3.4 and earlier matched when any occurrence differed. Wireshark 4.0 introduced additional explicit operators, including any_ne, all_ne, ===, and !==, providing greater control over multiple field occurrences. To exclude packets containing a particular address in any occurrence, use an explicit negation such as !(ip.addr == 192.168.11.65). Remember that this expression also matches packets in which ip.addr does not exist; add an existence test if those packets should be excluded.


The contains operator performs a literal substring or byte-sequence search, while matches evaluates a case-insensitive Perl-compatible regular expression (PCRE2) against string-compatible fields. Both can operate on data exposed through protocol dissection, including reassembled application data where the relevant dissector supports reassembly and the necessary preferences are enabled. Consequently, content spanning multiple TCP segments may not be available for matching when reassembly is disabled or incomplete.


Additional operators include in for set and range membership and bitwise & for flag testing. For example, tcp.flags & 0x02 identifies packets with the TCP SYN flag set, while tcp.port in {80, 443} selects packets containing either port value. These operators provide more precise filtering capabilities, particularly when examining multiple field occurrences or protocol flags. Consult the Wireshark User's Guide and the wireshark-filter(4) manual page corresponding to the version used during examination. Record the Wireshark version and relevant configuration settings to ensure that filtering results are reproducible.



The contains operator performs a case-sensitive, literal substring match against a field. The filter dns.qry.name contains "timeserversync.com" selects DNS packets whose decoded question name contains that string. DNS responses commonly include the original question section, so the filter can match both queries and their corresponding responses. The same lookup may also appear multiple times if a client queries more than one resolver, as observed in this capture, where 192.168.99.51 sends identical queries, using the same transaction ID, to 208.67.222.222 and 208.67.220.220. Identical transaction IDs across different resolver destinations are not inherently suspicious because DNS transaction IDs are interpreted within the context of the communication.


These matches provide evidence of DNS resolution activity, not proof of an established network connection. The filter may not identify names appearing only in answer records without a corresponding question field, encrypted DNS traffic that Wireshark cannot decrypt, or domain references carried by non-DNS protocols. For case-insensitive matching, use lower(dns.qry.name) contains "timeserversync.com". Wireshark's lower() function converts string values to lowercase before comparison.


The results show four DNS lookups for www.timeserversync.com at intervals of approximately one hour, resolving through a CNAME record to 157.245.128.27. To investigate the recurring pattern, examine the DNS response TTL values, including those associated with the CNAME and subsequent A records, to determine whether cache expiry could explain the query frequency. Also consider whether a scheduled application or background process is generating periodic lookups. Finally, pivot to traffic involving 157.245.128.27 to determine whether subsequent network communication occurred. Record the Wireshark version, relevant capture details, and timestamps in UTC when documenting the findings.




The matches operator evaluates a Perl-compatible regular expression (PCRE2) against a string field, allowing matching criteria that contains cannot express, such as anchoring, grouping, and alternation. An unanchored pattern behaves like a substring match: dns.qry.name matches "timeserversync.com" selects DNS packets whose query names contain that string, including www.timeserversync.com. Anchors constrain matching to the beginning (^) or end ($) of the field value. For example, dns.qry.name matches "(^|\\.)timeserversync\\.com$" selects the domain timeserversync.com and its subdomains while excluding lookalikes such as notimeserversync.com. Escape regular-expression metacharacters because an unescaped period (.) matches any character. Also remember that backslashes must themselves be escaped within quoted Wireshark display-filter strings.



Wireshark's matches operator is case-insensitive by default. Examiners can explicitly control this behaviour using PCRE2 inline modifiers: (?i) for case-insensitive matching and (?-i) for case-sensitive matching. Explicitly specifying the intended behaviour improves filter reproducibility and avoids reliance on default settings. The filter dns.qry.name matches "(?i)(^|\\.)timeserversync\\.com$" selects packets whose DNS query names are timeserversync.com or its subdomains. The pattern requires the domain to begin at the start of the field or immediately after a dot, preventing matches against lookalike names such as notimeserversync.com.


Display filters and Find Packet serve different investigative purposes. A display filter such as dns.qry.name contains "timeserversync.com" returns the complete set of packets matching a condition on a dissected protocol field. This is useful when establishing the number of matches, when they occurred, and which hosts were involved. It also supports reproducibility because the exact filter expression can be recorded in examination notes and applied again to the same capture.


Find Packet, by contrast, allows an examiner to navigate between individual matches within the capture. It supports searches across packet bytes, packet details, and packet list columns, as well as searches for strings, hexadecimal values, and wide (UTF-16) strings. Searching raw packet bytes does not depend on successful protocol dissection, making this functionality useful when a dissector may have misidentified or incorrectly interpreted packet contents. However, byte searches operate on the captured frame data and do not automatically reconstruct application data spanning multiple TCP segments.


When additional context is required, an examiner does not need to rely solely on repeated searches or adjacent frames. After applying a display filter and identifying a packet of interest, record its frame number before clearing the filter. The examiner can then return to the packet in the full capture and examine its surrounding traffic. Alternatively, relevant packets can be marked to facilitate subsequent navigation. Because adjacent frames are not necessarily part of the same communication, conversation-level analysis often provides more meaningful context. For TCP traffic, the tcp.stream field can isolate packets belonging to the same TCP conversation, while Wireshark's Conversation Filter can help identify related communications. For DNS investigations, this can be extended to examining subsequent traffic involving the resolved IP address to determine whether network communication followed the resolution event.




Wireshark provides predefined display filters that serve as starting points for common analysis tasks and allows examiners to create and save their own expressions. Saved filters can be managed through Analyze → Display Filters or the bookmark icon on the filter toolbar. They are stored in the dfilters configuration file associated with the active configuration profile. Filter buttons are maintained separately in the dfilter_buttons file and provide convenient toolbar shortcuts for frequently used expressions. Although these configurations can be transferred or shared between workstations, they are not automatically synchronized across different installations or profiles. For forensic reproducibility, examiners should therefore record the complete filter expression, rather than relying solely on its saved name.


Frequently used expressions can also be added as filter buttons, allowing them to be applied directly from the toolbar. Additionally, selecting a protocol field in the packet details pane and choosing Apply as Filter immediately applies an expression based on that field. Prepare as Filter, by contrast, inserts the generated expression into the filter bar without immediately applying it, allowing the examiner to modify or extend the expression before use.



The Display Filters dialog (Analyze → Display Filters...) manages the saved display filters associated with the current configuration profile. Each row pairs a descriptive name with its corresponding filter expression. The predefined entries supplied with Wireshark use documentation-only addresses: the MAC address 00:00:5e:00:53:00, which falls within the documentation block specified in RFC 9542; 192.0.2.1, from the IPv4 TEST-NET-1 block; and 2001:db8::1, from the IPv6 documentation prefix. These values are examples rather than addresses to use as real network indicators. Use the buttons at the bottom of the dialog to add, delete, or copy an entry. Double-click a filter name or expression to edit it. This dialog manages saved filter definitions; it does not apply a selected filter to the current packet list. To apply a saved filter, select it from the bookmark menu beside the display-filter bar or use a configured display-filter button.


Wireshark stores saved display-filter definitions in the dfilters file within the configuration profile. Display-filter buttons are stored separately in dfilter_buttons. For forensic casework, consider using a dedicated configuration profile, recording the complete filter expression—not just its saved name—in your examination notes, and documenting the Wireshark version and relevant profile settings.



Saved display filters are also accessible through the bookmark icon to the left of the display-filter bar. The menu provides access to the saved filters available to the active configuration profile, displaying each filter by its descriptive name and expression. Selecting an entry places its expression in the filter bar; it does not immediately apply the filter. Press Enter or click the Apply button to evaluate the expression against the current packet list.


The menu also provides several management options. Save this filter saves the expression currently entered in the filter bar as a reusable display filter, while Remove this filter removes the applicable saved filter. Manage Display Filters opens the same management dialog accessible through Analyze → Display Filters..., and Filter Button Preferences... opens the settings for configuring display-filter buttons.


Because saved filter definitions are configuration-dependent, the available entries may differ between workstations or profiles. Wireshark reads the personal dfilters file for the active profile when available, falling back to the global configuration file if no personal file exists. For forensic casework, record the complete filter expression rather than relying solely on its saved name, and document the Wireshark version and configuration profile used.



When you know which protocol field you want to filter on but are unsure of its Wireshark abbreviation, Analyze → Display Filter Expression... opens a field browser that helps you construct a valid display-filter expression. The dialog lists filterable protocols and fields in a tree, showing protocol abbreviations alongside their full names. The abbreviation, such as dns or tcp, is the token used in display filters. Expanding a protocol reveals its individual filterable fields. After selecting a field, you can choose a relation appropriate to its data type, enter a value, select from predefined values where available, and specify an optional byte range. The available relations also determine how comparisons behave when a field occurs multiple times in a packet. For example, == matches when any occurrence equals the specified value, whereas === requires all occurrences to match. The expression preview shows the filter that will be inserted into the display-filter bar when you click OK.


The search box accepts full or partial field names and descriptions, and it also supports regular expressions. Consequently, searching for a short term such as tcp may return entries from several protocol dissectors. A more targeted search, such as ^tcp.flag, can help narrow the results to fields belonging to the TCP dissector. In practice, an even quicker way to identify a field name is to select the relevant item in the Packet Details pane and check the status bar, which displays its display-filter abbreviation. You can also right-click the item and choose Apply as Filter or Prepare as Filter to construct a filter directly.


Remember that field names and protocol dissectors can change between Wireshark releases. For example, the transition from SSL terminology to TLS terminology affected filter-field naming. Additionally, if a protocol dissector is disabled, Wireshark may not generate the fields associated with it, causing filters that depend on those fields to return no matches. When investigating unexpected filter results, check the enabled protocols and consult the display-filter reference for the Wireshark version in use.



To select packets containing TCP segments with a header length of exactly 20 bytes, open Analyze → Display Filter Expression..., search for hdr_len, and select tcp.hdr_len (Header Length). The dialog presents the relations supported by the selected field's data type. Because tcp.hdr_len is an unsigned integer, it supports numerical comparisons but not string or byte-sequence operators such as contains and matches. Select ==, enter 20, and the expression preview should display tcp.hdr_len == 20. Click OK to insert the expression into the display-filter bar, then press Enter or click Apply to evaluate it.


The value represents the TCP header length in bytes, corresponding to the Header Length shown in the packet details pane (for example, 20 bytes (5)). The number in parentheses is the Data Offset expressed in 32-bit words. Therefore, a 20-byte TCP header is the minimum permitted header length and contains no TCP options. The filter matches TCP segments with no options, regardless of their flags or connection state. To narrow the results to initial SYN packets without options, use:


tcp.flags.syn == 1 && tcp.flags.ack == 0 && tcp.hdr_len == 20


Modern operating systems commonly include TCP options in SYN segments, so a SYN without options may be worth examining when investigating connection establishment or comparing network-stack behavior. However, it is not inherently malicious; legitimate systems and network configurations can produce such traffic. Interpret the result alongside the source and destination, other packets in the connection, and the surrounding network context.



Once you are comfortable with the syntax, typing display filters directly is often faster than using the dialogs, and Wireshark's autocomplete feature can help you identify field names. There are different ways to select UDP-related traffic, and the filters answer different questions. The expression ip.proto == 17 tests the Protocol field in an IPv4 header, where the value 17 identifies UDP. It therefore selects IPv4 packets whose Protocol field specifies UDP, including non-initial IPv4 fragments that do not contain a UDP header. It may also match an inner IPv4 header, such as the original packet header quoted inside an ICMP error message. For IPv6, ipv6.nxt == 17 tests the Next Header field. However, this requires care because IPv6 extension headers can appear between the IPv6 base header and the UDP header. In such cases, the base header's Next Header field identifies the first extension header rather than UDP.


The filter udp, by contrast, selects packets in which Wireshark has dissected a UDP protocol layer. This can include UDP carried over IPv4 or IPv6, as well as UDP identified within supported encapsulations. Unlike ip.proto == 17, it does not ordinarily match non-initial fragments because those fragments do not contain a UDP header. When IP fragment reassembly is enabled and successful, however, Wireshark may dissect the reassembled datagram and expose UDP fields. The udp filter can also match ICMP and ICMPv6 error messages when Wireshark dissects the quoted original packet and identifies its UDP header. To exclude packets dissected as ICMP or ICMPv6, you can use:


udp && !icmp && !icmpv6


This is useful when examining UDP traffic without the associated ICMP error messages, but it should not be treated as a definitive count of unique UDP datagrams. A single datagram may be represented by multiple captured fragments, and reassembly affects which frames expose UDP fields. Because these filters depend on different header fields and dissection behavior, unexpected results should prompt you to examine the packet details, fragmentation, encapsulation, and reassembly settings. For reproducibility, document the complete filter expression, Wireshark version, and relevant protocol and reassembly preferences.



As you type a display filter, Wireshark's autocomplete feature suggests protocol and field names. Typing a protocol abbreviation followed by a period displays available fields associated with that protocol. Accepting a suggestion (Tab or Enter in most builds) inserts its exact field name into the filter bar. This is particularly useful when you remember a field's purpose but not its precise abbreviation. It is also worth browsing the available completions for protocols you investigate frequently.


Among the TCP field suggestions, those beginning with tcp.analysis are different from ordinary TCP header fields. For example, tcp.flags.ack corresponds to the ACK bit in the TCP header, whereas tcp.analysis.ack_rtt is a value calculated by Wireshark rather than a field transmitted in the packet. Wireshark derives tcp.analysis.ack_rtt by tracking TCP conversations and associating an observed acknowledgment with the segment it acknowledges. The expression tcp.analysis.ack_rtt > 0.5 selects packets with a calculated acknowledgment RTT greater than 0.5 seconds. This value represents the time between observing the original segment and observing its acknowledgment at the capture point. It should not automatically be interpreted as application response time or a definitive measurement of network latency.


These generated analysis fields are useful for troubleshooting, identifying unusual TCP behavior, and locating packets for closer examination. However, their interpretation depends on the packets available to Wireshark and its analysis settings. TCP analysis is stateful: Wireshark processes packets in the order in which they appear in the packet list and maintains information about each TCP session. Captures that begin after a connection has been established, omit packets, contain packets in an unusual order, or observe only one direction of a conversation can limit the accuracy of its conclusions. For example, an ACK that cannot be associated with a previously observed segment may not have a corresponding tcp.analysis.ack_rtt value. Similarly, missing traffic can affect retransmission and out-of-order classifications. Verify important findings against the underlying packet sequence and surrounding conversation rather than treating an analysis flag or calculated value as conclusive evidence.



Wireshark can generate display filters from decoded fields selected in the Packet Details pane. Right-click a field and choose Apply as Filter to construct and immediately apply an expression, or Prepare as Filter to insert the expression into the filter bar without applying it, allowing you to edit or combine it with other conditions first. The available submenu options include Selected and Not Selected, as well as combinations that join the new condition to the existing filter using AND or OR, with or without negation. These options make it easy to build complex expressions without manually typing every field name and value.


The generated expression depends on the specific field selected. For example, selecting ip.src restricts the match to the source IP address, whereas ip.addr matches either the source or destination address. This distinction matters when investigating traffic direction or identifying communications involving a particular host. Other Wireshark features also provide convenient filtering shortcuts. Conversation Filter generates a filter based on the endpoints of the selected conversation, while Follow Stream opens the stream-following interface and isolates the relevant stream. Field-based Packet List columns can also be used to construct filters, depending on the selected column and available context-menu options.


Always inspect the generated expression before relying on it. When combining conditions manually, use parentheses where necessary to make the intended logical grouping explicit and avoid unintended changes in operator precedence. Pay particular attention to TCP sequence-number fields. Wireshark can display relative sequence numbers, which are calculated from the first observed segment in a conversation. For filters that must use absolute sequence or acknowledgment numbers, use tcp.seq_abs and tcp.ack_abs rather than relying on relative values. Record the final expression, Wireshark version, and relevant TCP preferences in your examination notes rather than documenting only the menu operations used to create the filter.



In the Packet Details pane, right-click a decoded field and choose Apply as Filter → Selected to construct and apply a display filter using the selected field's value. In this example, the DNS Transaction ID 0xb9f6 is selected in frame 187600, a DNS response from 208.67.222.222. The context menu previews the expression dns.id == 0xb9f6 before it is applied. The status bar also confirms the underlying field abbreviation as dns.id. The resulting filter matches DNS packets containing that transaction ID, potentially including the original query, its response, and duplicate queries sent to other resolvers. However, the transaction ID is only 16 bits long, so unrelated DNS transactions in a large capture can use the same value. Furthermore, a duplicate query sent to another resolver may reuse the original ID, but this behavior is not guaranteed. For more reliable correlation, narrow the results using the client and resolver addresses, transport ports, and DNS query name where available. For example:


dns.id == 0xb9f6 && dns.qry.name == "example.com"


You can further constrain the expression using ip.addr for IPv4 endpoints or ipv6.addr for IPv6 endpoints. Remember that a DNS transaction should be correlated using its surrounding context, not its transaction ID alone. The and Selected, or Selected, and related combination options are available when an expression already exists in the display-filter bar. They allow the selected field condition to be combined with the existing filter. Alternatively, Prepare as Filter inserts the expression into the filter bar without applying it, making it useful when constructing compound filters. For forensic reproducibility, record the complete final expression in your examination notes rather than documenting only the menu operations used to create it.



The right-click filter-generation functionality is also available in several Wireshark statistics dialogs. In Statistics → Protocol Hierarchy, right-click a protocol row and choose Apply as Filter or Prepare as Filter to generate a display filter for that protocol. For example, selecting the DNS row can generate dns, while selecting the Data row can generate data. The resulting protocol filter selects packets containing that protocol layer, including packets in which it appears beneath another protocol. Consequently, the number of packets matched by a filter such as dns can exceed the DNS row's End Packets count. The Packets column reports the total number of packets containing the protocol, whereas End Packets reports packets in which that protocol was the highest (last dissected) protocol in the stack.


Protocol Hierarchy is useful for first-pass traffic triage. Unexpected protocols, unusual traffic proportions, and a large proportion of packets classified as data can provide useful leads for further investigation. However, these observations are not findings by themselves. Protocol identification depends on factors such as port assignments, enabled heuristic dissectors, protocol preferences, and capture completeness. The data label generally indicates payload that Wireshark has not dissected as a more specific protocol; it does not necessarily indicate malicious or unexplained activity.


If a display filter was active when the Protocol Hierarchy dialog was opened, check whether Limit to display filter is enabled. When enabled, the statistics reflect only packets matching the active display filter rather than the entire capture. Document this setting when recording or comparing protocol statistics. The Conversations and Endpoints dialogs also provide filter-generation options when you right-click a selected row. These filters isolate traffic associated with the selected conversation or endpoint and are useful for investigating communication relationships.


Apply as Filter and Prepare as Filter appear side by side in Wireshark's context menus and offer the same submenu options: Selected, Not Selected, and the AND/OR combinations. Apply as Filter constructs the expression and evaluates it immediately. Prepare as Filter constructs the same expression but inserts it into the display-filter bar without applying it. This allows you to inspect, edit, and combine multiple conditions, including adding parentheses, before evaluating the completed expression. The Selected and Not Selected options replace the current contents of the filter bar, while the AND/OR combinations append the new condition to the existing expression. These combination options are available only when the filter bar already contains an expression.


For compound filters, Prepare as Filter is generally the safer approach because it allows you to review the complete expression before execution. It can also save time when working with large captures by avoiding repeated evaluation of intermediate expressions. However, it does not reduce the computational cost of evaluating the final expression. For very large captures, consider reducing the data being examined where appropriate. A BPF capture filter can restrict packets during a new capture, while TShark can extract matching packets from an existing capture using an offline display filter. For example:


tshark -r input.pcapng -Y "dns" -w dns_only.pcapng


This writes packets matching the DNS display filter to a separate capture file without modifying the original. Preserve the original capture and document the extraction command and the resulting file's hash. For forensic reproducibility, record the complete final display-filter expression rather than merely documenting the menu operations used to construct it.



Wireshark retains a history of recently applied display filters. You can recall a previous expression using the recent-filter drop-down beside the display-filter bar, allowing you to revisit a carefully constructed filter without having to recreate it. The history is maintained in the recent_common configuration file, which stores common GUI settings, including recently used display filters, recently opened capture files, and window geometry. On modern Linux systems, this file is typically located at ~/.config/wireshark/recent_common. The file is read when Wireshark starts and written when preferences are saved or the application exits. Consequently, recent-filter history normally persists across sessions, although changes made since the last write may not survive an unexpected application crash.


The recent-filter and recent-capture-file lists are separate lists, even though their information is stored in the same configuration file. Recently opened captures can be accessed through File → Open Recent and the welcome screen. The number of entries retained in these lists is configurable. You can locate the relevant configuration directories through Help > About Wireshark > Folders. Because recent history may contain case-specific filter expressions, capture filenames, and file paths, consider using an appropriate examination environment and clearing sensitive history when a matter is concluded.


Do not rely on recent history as a filter-sharing mechanism. To preserve or distribute reusable expressions, save them using Save this filter, create display-filter buttons, or export the appropriate configuration profile. For forensic reproducibility, record the complete final expression and Wireshark version in your examination notes. Recent-filter history is not a substitute for a documented examination methodology.


Extracting Evidence

To create an evidence subset, first isolate the packets of interest. In this example, a suspicious email was identified in an SMTP session between a client using TCP port 64770 and a mail server listening on port 25. Selecting Follow > TCP Stream applies the display filter tcp.stream eq 0, restricting the packet list to the 14 packets associated with that TCP conversation, including the handshake and connection teardown.




The reconstructed stream reveals a password-reset lure containing a URL pointing to evil[.]com. This is an indicator of a potential phishing attempt, although the destination site's actual behavior and any subsequent credential-harvesting activity must be established through additional evidence, such as follow-on network traffic. With the relevant stream displayed, select Edit > Mark All Displayed (Ctrl+Shift+M). This marks every packet currently visible in the packet list. Packet marks are temporary annotations maintained in Wireshark's in-memory state; they are not stored in the original capture file and are lost when the capture is closed. To preserve the selected packets, choose File > Export Specified Packets... and select Marked packets in the Packet Range section. Check whether the Captured or Displayed option is selected to ensure the export contains the intended packets. Save the result as a separate capture file, preserving the original evidence unchanged.


Calculate and record cryptographic hashes, preferably SHA-256, for both the original capture and the exported subset. Also document the selection criteria, packet count, export settings, and Wireshark version. Because TCP stream indexes are assigned during dissection and are specific to the capture, record the endpoint IP addresses, port numbers, and relevant timestamps in addition to the filter expression. If you need to recover the email itself, use File > Export Objects > IMF when Wireshark has successfully reconstructed the message. The IMF dissector requires SMTP message reassembly to be enabled where the message spans multiple TCP segments. Inspect the exported message and its MIME content rather than relying exclusively on the text displayed in Follow TCP Stream.


For individual packets, Mark/Unmark Packet (Ctrl+M) provides a convenient way to toggle the marked state. However, when creating a reproducible evidence subset, applying a documented display filter and using Mark All Displayed provides a clearer selection procedure. Preserve the filter expression and export details in your examination notes.



The email message itself can be extracted using File > Export Objects > IMF, which writes the reconstructed message to a file for content analysis. To preserve the surrounding network evidence, however, we also need to identify and collect the related packets.


The email contains a URL referencing evil[.]com, so the next step is to investigate whether the domain appears in DNS traffic. The display filter dns.qry.name contains "www.evil.com" selects frames 302 and 303 in this example: a DNS query from 173.255.224.59 to the resolver at 173.255.224.8, followed by the corresponding response. The response also matches because it repeats the question name in its DNS question section. The contains operator performs a case-sensitive literal substring search. Consequently, this filter would miss case variants and other subdomains, and it is not an exact-hostname comparison. To match evil.com and its subdomains, use the regular expression:


dns.qry.name matches "(?i)(^|\\.)evil\\.com$"


Wireshark's matches operator is case-insensitive by default, so the (?i) flag is optional here. With the DNS packets displayed, select Edit > Mark All Displayed. This adds the displayed packets to the existing marked-packet set, preserving the packets previously marked from the SMTP stream. The DNS response indicates that the resolver returned an answer for the queried name. Inspect its response code and answer records to determine whether it returned an address directly or, for example, a CNAME that requires further resolution. This lookup does not establish why the name was queried, whether a user opened the email link, or whether the host subsequently connected to the site. Treat the relationship between the email and the DNS lookup as a hypothesis to test against additional evidence. The next pivot is the address returned in the DNS response. Search for traffic involving that address to determine whether the host established a connection and what data was exchanged. Consider the timing, destination port, connection details, and available application-layer evidence before attributing the traffic to the email.


After marking the relevant packets from each investigative step, apply frame.marked == 1 to review the combined evidence set. Then select File > Export Specified Packets... and export the marked packets as a separate capture file. In the export dialog, verify the Marked packets option and the Captured or Displayed scope; the latter can further restrict the export according to the active display filter. For reproducibility, record the filters used, the frames identified at each step, and the final number of unique marked packets. Be careful not to add per-step packet counts as though they were necessarily unique, since the same frame may be relevant to more than one step. Hash both the original capture and the exported subset, and document the Wireshark version and relevant export settings. Packet marks are not saved with the capture file, so preserve the exported subset and investigation notes before closing the original capture.



Once all packets identified as relevant to the incident have been marked, apply the filter frame.marked == 1 to review the complete marked set. Record the original frame numbers in your investigation notes, because packets in the exported capture will be renumbered starting at frame 1. Next, select File > Export Specified Packets.... In the Packet Range section, select Captured and Marked packets only. This exports all marked packets, regardless of whether a display filter is currently active. Confirm that the packet count matches your notes—in this example, 25 packets. The adjacent First to last marked option behaves differently: it exports every packet between the first and last marked frames, including packets that were not marked. In this example, that range extends through frame 303. Use this option only when you intentionally want the intervening traffic included. Save the exported capture in a separate output directory, keeping it distinct from the original evidence file. Prefer the same capture format as the source where practical. If the original is pcapng and contains packet comments, interface information, or other metadata that must be retained, export in pcapng format rather than classic pcap, which cannot preserve all pcapng features.


After exporting, open the new file and verify its packet count, first and last timestamps, and expected packets, endpoints, and protocols. Where traceability is important, retain a mapping between the original frame numbers and the renumbered frames in the exported file. Calculate and record SHA-256 hashes for both the original capture and the exported subset, and document the Wireshark version and export settings. Remember that the exported file contains only the packets selected during the investigation; it does not necessarily contain all evidence relevant to the incident. In this example, the last marked packet is frame 303, so any follow-on traffic after the DNS lookup is excluded. Preserve the original capture as the primary evidentiary source and treat the exported file as a derived evidence subset. Because packet marks are not saved with the capture, complete and verify the export during the same Wireshark session.


Display filters are one of the primary tools for selecting and analyzing packets in Wireshark. Because they operate on fields exposed by protocol dissectors, they can express criteria beyond the capabilities of traditional BPF capture filters. These include application-layer values, fields made available through protocol reassembly, and dissector-generated analysis fields such as tcp.analysis.ack_rtt. Display filters can be created in several ways: by typing expressions directly into the filter bar and using autocomplete; through the Display Filter Expression dialog; by selecting saved filters or filter buttons; and by right-clicking fields, statistics entries, or packets to use options such as Apply as Filter and Prepare as Filter. This flexibility depends on successful protocol dissection. Results can be affected by protocol identification, enabled dissectors, reassembly and analysis preferences, capture completeness, and Wireshark version. An empty result therefore means that no packets matched the expression under the current conditions; it does not prove that the underlying traffic or activity was absent.


BPF capture filters and Wireshark display filters serve complementary purposes. Use BPF filters when capturing traffic to reduce the volume of packets collected, then use display filters to investigate protocol-specific details in the resulting capture. Marking and exporting can help preserve a focused subset of packets for further analysis, while the original capture remains the primary evidentiary source. For reproducibility, document the exact filter expressions, Wireshark version, relevant preferences, and any capture or export settings. Calculate and record hashes for the original capture and any derived files, and retain sufficient notes to explain how each evidence subset was selected.

Post a Comment

Previous Post Next Post