All FortiGate units have a powerful packet sniffer on board. If you know tcpdump you should feel comfortable using the FortiGate Sniffer.
See the related article "Packet capture (sniffer) tips" for additional sniffer tips.
Scope : All FortiOS
Note : Other Fortinet appliances also providing a CLI sniffer : FortiAnalyzer - FortiMail - FortiManager
----internal----| FortiGate |---external-----
The packet sniffer "sits" in the FortiGate and can sniff traffic on a specific Interface or on all Interfaces. There are 3 different Level of Information, also known as Verbose Levels 1 to 3, where verbose 1 shows less information and verbose 3 shows the most information. Verbose 4, 5 and 6 would additionally provide the interface details
Verbose levels in detail:1: print header of packets
2: print header and data from IP of packets
3: print header and data from Ethernet of packets
4: print header of packets with interface name
5: print header and data from IP of packets with interface name
6: print header and data from Ethernet of packets with interface name
This article walks through some examples and different levels of verbosity to show the different possibilities for debugging.
All Packet sniffing commands start like:
# diag sniffer packet <interface> <'filter'> <verbose> <count> a
<interface> can be an Interface name or "any" for all Interfaces.
Sniff 3 packets of all traffic with verbose Level 4 on internal Interface
# diag sniffer packet internal none 4 3
As you can see we caught some Packets in the middle of a communication. Because the 192.168.0.1 IP Address uses Port 22 (192.168.0.1.22) we can assume that we've caught some Packets from a running SSH Session. The "none" variable means 'no filter applies', "4" means 'verbose 4' and "3" means 'catch 3 packets and stop'.
Sniff 3 packets of all traffic with verbose Level 4 on Internal interface
# diag sniffer packet internal none 4 3
Apparently we caught some more interesting information, just when a TCP session was being set up. 192.168.0.30 tries to connect to 192.168.0.1 on Port 80 with a syn and gets a syn ack back. Finally the session is acknowledged and established after the 3-way TCP handshake.
With information level set to Verbose 4, we see a summary of Source and Destination IP Address, as well as Source and Destination Port. We can also see the corresponding TCP Sequence numbers.
If you don't enter a <count> value, the Sniffer runs forever until you stop it with <CTRL C>
Hint: For further investigation it's always a good idea to log to a file. If you're using Putty (a free SSH client for Windows) you can easily log all Output to a file which you can search/sort/process.
Verbose 5 and Verbose 6 levels:
Verbose 5 contains much more information
1. The IP Header as we've already seen in Verbose 4
An Output of Verbose 5 looks like this:
# diag sniffer packet internal none 5 1
0x0000 4510 005c 8eb1 4000 4006 2a6b c0a8 0001 E..\..@.@.*k....
Notice the in/ out parameter after internal interface that will confirm the direction of the packet entering or leaving the interface.
Verbose 6, finally, even includes Ethernet (Ether Frame) Information. A script is available (fgt2eth.pl), which will convert a captured verbose 6 output, into a file that can be read and decoded by Ethereal/Wireshark. See the end of this article for details.
Use of absolute time stamp in sniffer trace will report the absolute system time (no time zone) in packet summary:
# diag sniffer packet internal none 4 2 a
2010-06-02 10:23:17.170751 port1 out arp who-has 192.168.1.110 tell 192.168.1.103
Hint: Below is the format that Technical Support will usually request when attempting to analyze a problem as it includes full packet content, as well as absolute time stamp, in order to correlate packets with other system events.
# diag sniffer packet any <'filter'> 6 0 a
As already mentioned: diag sniffer includes a powerful filter functionality that will be described here.
FortiOS tells us:
<filter> filter for sniffer
If a second host is specified, only the traffic between the 2 hosts will be displayed.
<filter> flexible logical filters for sniffer (or "none").
Imagine you only want to sniff the traffic from one PC to another PC. Without Filter the sniffer will display all packets which is far too much and painful to debug.
To see what's going on between two PCs (or a PC and a FortiGate),(Don't forget to put your filter expressions in single quotes ' ' ):
# diag sniffer packet internal 'src host 192.168.0.130 and dst host 192.168.0.1' 1
192.168.0.130.3426 -> 192.168.0.1.80: syn 1325244087
Assuming there is a lot of traffic on the wire, this filter command will only display traffic (but all traffic) from Source 192.168.0.130 to Destination 192.168.0.1. It will NOT show traffic to 192.168.0.130 (for example the ICMP reply) because we said ' src host 192.168.0.130 and dst host 192.168.0.1'
As you can see we also captured some other things like ICMP or DNS queries from a PC. If we're just interested in a specific type of traffic (let's say TCP Traffic only) we need to change our filter command slightly like this:
# diag sniffer packet internal 'src host 192.168.0.130 and dst host 192.168.0.1 and tcp' 1
192.168.0.130.3569 -> 192.168.0.1.23: syn 1802541497
Though ICMP (ping) was also running, the trace only shows the TCP part. As we can see the Destination is: 192.168.0.1.23 which is IP 192.168.0.1 on Port 23. Apparently we found a Telnet Session to 192.168.0.1 right during initial setup.
The same the other way around:
# diag sniffer packet internal 'host 192.168.0.130 and icmp' 1
192.168.0.130 -> 192.168.0.1: icmp: echo request
In this example we're sniffing for ICMP only, to and from 192.168.0.130
Another useful feature is logical combination. Let us assume you want to sniff for ICMP and TCP only (but not for UDP, ARP, etc). You can combine protocols in the following manner:
# diag sniffer packet internal 'host 192.168.0.130 and (icmp or tcp)' 1
This sniff will display all tcp or icmp traffic to and from host 192.168.0.30, in verbose 1 level.
Now we are going to limit the sniffer even more:
We want to sniff traffic between 2 hosts, but only TCP and only port 80.
# diag sniffer packet internal 'host 192.168.0.130 and 192.168.0.1 and tcp port 80' 1
192.168.0.130.3625 -> 192.168.0.1.80: syn 2057246590
A logical "and" is used in this command between 192.168.0.130 and 192.168.0.1 so that only packets containing both these host addresses will be seen.
Even if telnet and ssh is running between the two hosts, we only see port 80 TCP traffic.
Filtered can be used to display packets based on their content, using hexadecimal byte position.
Match TTL = 1
Match Source IP address = 192.168.1.2:
Match Source MAC = 00:09:0f:89:10:ea
Match Destination MAC = 00:09:0f:89:10:ea
Match ARP packets only
TCP or UDP flags can be addressed using the following:
Match packets with RST flag set:
Match packets with SYN flag set:
Match packets with SYN-ACK flag set:
Also attached is the fgt2eth.pl script that will convert a verbose level 3 or 6 sniffer output, into a file readable and decodable by Ethereal/Wireshark.
The fgt2eth.exe file is also attached to this article, this file is outdated and is not supported but may provide some guidance.
Note: The attached script is provided "as is", it is not supported by Technical Support.