FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
Matt_B
Staff & Editor
Staff & Editor
Article Id 369498
Description This article illustrates the use of some advanced filters that can assist in troubleshooting network issues.
Scope FortiGate.
Solution

FortiOS uses libpcap/BPF pcap-filter arguments. For reference see libpcap documentation such as 'PCAP-FILTER(7) MAN PAGE'. Note that only packets handled by the CPU can be captured. Ensure that hardware offload is disabled for the relevant policy or function before capturing.

 

See below for some examples.

 

Capturing ARP requests and replies with EtherType 0x0806:

ARP requests and replies use EtherType 0x0806. It is possible to filter further using an IP address that is the subject of the ARP message.


SPOKE-1 # diagnose sniffer packet any 'ether proto 0x0806 and host 10.255.144.7' 4 100 l
interfaces=[any]
filters=[ether proto 0x0806 and host 10.255.144.7]
2025-01-09 16:37:03.918024 wan1 out arp who-has 10.255.144.7 tell 10.255.144.29
2025-01-09 16:37:04.917709 wan1 out arp who-has 10.255.144.7 tell 10.255.144.29
2025-01-09 16:37:05.917710 wan1 out arp who-has 10.255.144.7 tell 10.255.144.29
2025-01-09 16:37:06.918088 wan1 out arp who-has 10.255.144.7 tell 10.255.144.29


Other Ethertypes are also supported for capturing other traffic of interest, including FortiGate HA Heartbeat packet Ethertypes.

 

Specific ICMP messages:

ICMP unreachable messages related to a flow will not typically appear on a packet sniffer filtered by destination IP address. To extend the filter to include all ICMP destination unreachable messages, include an 'or' filter for ICMP type 3. Optionally include an ICMP code.

The following example captures ICMP 'Fragmentation Needed' messages.

 

HUB # diagnose sniffer packet any 'host 10.100.1.1 or (icmp[icmptype] == 3 and icmp[icmpcode] == 4)' 4 1000 l
interfaces=[any]
filters=[host 10.100.1.1 or (icmp[icmptype] == 3 and icmp[icmpcode] == 4)]
2025-01-10 10:22:59.821729 port16 in 10.255.144.29 -> 10.100.1.1: icmp: echo request
<--- captured by 'host 10.100.1.1' filter.
2025-01-10 10:22:59.821771 port16 out 10.255.144.1 -> 10.255.144.29: icmp: 10.100.1.1 unreachable - need to frag (mtu 900)
<--- captured by 'icmp[icmptype] == 3 and icmp[icmpcode] == 4' filter.

 

Fragmented Packets:

The following example captures fragmented packets.

 

diagnose sniffer packet any '(ip[6]&32==32 or ip[7]!=0)' 4 0 l
2018-09-15 19:29:12.407501 wan1 in 10.200.1.133 -> 10.244.21.41: icmp: echo request (frag 36978:1480@0+)
2018-09-15 19:29:12.407508 wan1 in 10.200.1.133 -> 10.244.21.41: ip-proto-1 (frag 36978:328@1480)
2018-09-15 19:29:12.407560 wan1 out 10.200.1.133 -> 10.244.21.41: icmp: echo request (frag 36978:1480@0+)
2018-09-15 19:29:12.407566 wan1 out 10.200.1.133 -> 10.244.21.41: ip-proto-1 (frag 36978:328@1480)

 

Third-Party ICMP documents:

RFC 792 Internet Control Message Protocol 

IANA ICMP parameters reference



Inbound frames on the specific interface:

When sniffing using the 'any' interface, inbound and outbound frames will be marked with 'in' or 'out'. However, the destination MAC address is replaced when sniffing on this interface.

 

SPOKE-1 # diagnose sniffer packet any 'port 22' 6 2 l
interfaces=[any]
filters=[port 22]
2025-01-10 11:24:44.109699 wan1 out 10.255.144.29.20912 -> 10.255.144.1.22: syn 560581361
0x0000 0000 0000 0000 e023 fffd cd02 0800 4540 .......#......E@
...

2025-01-10 11:24:44.109786 wan1 in 10.255.144.1.22 -> 10.255.144.29.20912: syn 3631446142 ack 560581362
0x0000 0000 0000 0001 0009 0faa cd12 0800 4540 ..............E@
...

 

To verify whether a packet was received or sent on an interface while preserving the MAC address in the capture, start a packet capture using the specific interface to capture the keyword 'inbound' or 'outbound'. Note the capture will show only inbound or outbound packets, not the complete flow.

 

SPOKE-1 # diagnose sniffer packet wan1 'port 22 and inbound' 6 1 l
interfaces=[wan1]
filters=[port 22 and inbound]
2025-01-10 11:26:55.524491 wan1 -- 10.255.144.1.22 -> 10.255.144.29.20917: syn 3255345877 ack 3835489971
0x0000 e023 fffd cd02 0009 0faa cd12 0800 4540 .#............E@
...


Packet sniffer with grep command:

Packet sniffer output can be passed to the grep command using the pipe '|' character. When used in this way, the capture filter determines which packets will be captured, but only lines matching the grep filter will be output.

HUB # diagnose sniffer packet any 'esp' 4 1000 l | grep "spi=0xa5638e7e"
interfaces=[any]
filters=[esp]
2025-01-10 12:29:27.076317 port16 out 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x41)
2025-01-10 12:29:43.609432 port16 out 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x42)
2025-01-10 12:29:44.609451 port16 out 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x43)
2025-01-10 12:29:45.180030 port16 out 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x44)


Custom filters:

Custom locations within a datagram can be accessed using (proto[offset:size]==0x<hexadecimal value>). Size of location checked can be 1, 2, or 4 bytes.


In Technical Tip: How to sniff packets by MAC Address on FortiGate with CLI commands, multiple custom filters are combined to sniff for a 6-byte MAC address.

 

'ether[0:4]=0x00090f89' <--- first 4 bytes of ethernet header
'ether[4:2]=0x10ea' <---- 5th and 6th bytes of ethernet header

'(ether[0:4]=0x00090f89) and (ether[4:2]=0x10ea)' <-- first 6 bytes of ethernet header, ie the destination MAC address.

 

Bytes checked can be within the datagram header or body. For example, the IPv4 source address exists in bytes 13-16 of the IPv4 packet. If the size of the Ethernet header is known, ether[] can be used to match IPv4 source address by adding 12 bytes of offset, even though IP address is not part of the Ethernet protocol.

 

Untagged: 14 bytes, IPv4 source address at ether[26:4]

802.1Q: 18 bytes, IPv4 source address at ether[30:4]

802.1ad "Q-in-Q": 22 bytes. IPv4 source address at ether[34:4]

 

Example sniffer on wan1 for all untagged packets with the IPv4 source address 10.255.255.100 (hexadecimal value 0x0affff64):

diagnose sniffer packet wan1 'ether[26:4]==0x0affff64'


As another example, the 4-byte SPI header for IPsec data traffic appears in ESP traffic. While no predefined filter exists, SPI can still be filtered using '(ip[20:4]==0x<SPI>)' when NAT-Traversal is not in use, or '(udp[8:4]==0x<SPI>)' when NAT traversal is in use.

 

HUB # diagnose sniffer packet port16 'ip[20:4]==0xa5638e7e' 4 2
interfaces=[port16]
filters=[ip[20:4]==0xa5638e7e]
port16 -- 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x118)
port16 -- 10.255.144.1 -> 10.255.144.30: ESP(spi=0xa5638e7e,seq=0x119)

 

HUB # diagnose sniffer packet port16 'udp[8:4]==0xe32be0a1' 4 2
interfaces=[port16]
filters=[udp[8:4]==0xe32be0a1]
port16 -- 10.255.144.1.4500 -> 10.255.144.29.4500: udp 132
port16 -- 10.255.144.1.4500 -> 10.255.144.29.4500: udp 132

 

See the article 'Technical Tip: Different methods to capture packets for IPsec VPN tunnels troubleshooting' for more details on packet capture for IPsec tunnels including how to find the correct SPI.

 

Incoming ESP packets for the FortiGate will only be shown if npu-offload was previously disabled for the tunnel under 'config VPN ipsec phase1-interface'.


Filter packets by VXLAN 'VNI value':

VNI is a 3-byte value. In a typical Ethernet VXLAN frame, VNI occupies the 47th, 48th, and 49th bytes. To capture traffic based on a specific VNI, convert the decimal VNI into hexadecimal first.

 

For example, a VNI with the nonstandard decimal value [93] is equivalent to the hexadecimal value [0x5d]

 

HUB # diagnose sniffer packet LAG_VXLAN '(ether[46:2]=0x0000) and (ether[48:1]=0x5d)' 6 10 l

interfaces=[LAG_VXLAN]
filters=[ether[48:1]=0x5d]
2025-05-19 15:39:14.362684 LAG_VXLAN -- 172.28.4.26.4829 -> 172.28.0.1.4789: udp 82
0x0000 0009 0f09 5524 0009 0f09 1824 0800 4500 ....U$.....$..E.
0x0010 006e 130e 0000 3f11 0c1e ac1c 041a ac1c .n....?.........
0x0020 0001 12dd 12b5 005a d69c 0800 0000 0000 .......Z........
0x0030 5d00 0009 0f09 0620 906c ac5a 2c62 0800 ]........l.Z,b..
0x0040 4500 003c 96f7 4000 4006 5f4f ac19 0a01 E..<..@.@._O....
0x0050 602d 2e2e 23f5 0355 a9d4 33e0 0000 0000 `-..#..U..3.....
0x0060 a002 ffff 044e 0000 0204 0582 0402 080a .....N..........
0x0070 54ef a57a 0000 0000 0103 030d T..z........

 

Screenshot packet detail.jpg

 

Related articles:

Troubleshooting Tip: Using the FortiOS built-in packet sniffer for capturing packets
Technical Tip: How to sniff packets by MAC Address on FortiGate with CLI commands