1 What a flow is
A router or sensor groups packets by their 5-tuple: source address, destination address, source port, destination port, protocol. Packets with the same key are counted into one record until the flow ends (a TCP FIN or RST), stays idle for the inactive timeout (often 15 s), or has run for the active timeout (often 30 min). A long transfer can therefore appear as several consecutive records.
- Unidirectional (NetFlow v5, many routers): one record per direction. A web request becomes two records, client → server and server → client.
- Bidirectional (IPFIX biflows, Zeek): one record per connection, with originator and responder counters.
The tool below groups the packets of the sample capture from the Packets page both ways:
From packets to flows
2 NetFlow v5 byte by byte
A NetFlow v5 export is a UDP packet from the router to a collector: a 24-byte header and up to 30 fixed records of 48 bytes, all big-endian. Record times are milliseconds of router uptime, not clock times. The header gives the uptime and the router's clock at export; together they turn every record time into a real time:
time = unix_secs − (sys_uptime − First) / 1000
Records 1 and 2 are the web request from the sample capture, one record per direction; compare their packets and bytes with the flow builder above. Record 4 is the TLS connection from the same capture, but the router kept counting after the capture ended: the client sent 88 MB to port 443 within five minutes, the TCP flags contain SYN but no FIN, and it ended 1.2 s before the export. The connection was probably still running and was exported by the active timeout or a cache flush: look for the next record with the same 5-tuple.
NetFlow v9 and IPFIX (sometimes called v10) replace the fixed layout by templates sent by the exporter, which allows extra fields such as application names or bidirectional counters. The principle stays the same.
3 Zeek conn.log
Zeek (formerly Bro) writes one line per connection to conn.log, tab-separated, with a header that lists
the fields. The uid links the line to the same connection in dns.log, http.log,
ssl.log or files.log.
| Field | Meaning |
|---|---|
ts | first packet, Unix epoch (UTC) |
id.orig_h / id.orig_p | originator (who sent the first packet) and its port |
id.resp_h / id.resp_p | responder and port |
service | protocol Zeek recognised in the payload (dns, http, ssl, smb, …), whatever the port |
duration, orig_bytes, resp_bytes | length and payload bytes in each direction |
conn_state | how it went: SF normal open and close, S0 SYN without answer,
REJ rejected, RSTO/RSTR reset by originator/responder, S1 still open |
history | packet letters: S SYN, h SYN-ACK, A ACK,
D data, F FIN, R RST; upper case = originator, lower case = responder |
4 Using flows in an investigation
- Direction and volume. Exfiltration looks like large outbound byte counts to an external address, often with little coming back.
- Baselines. One big upload proves nothing until you know what is normal. Backups, software updates and video calls move gigabytes every day. Compare with the same host, the same hour, the previous weeks.
- Beaconing. Malware calls home at regular intervals: many small flows to the same destination, evenly spaced.
- Vantage point. A router exporting on its inside interface sees internal addresses; on its outside interface it sees the NAT address, and all users look the same. Write down where the exporter sits.
- Sampling. Busy routers count only every n-th packet. Byte counts must be multiplied by the rate, and short flows can be missing entirely.
5 Try it yourself
Answer from the hex views and the flow table above.
How many flow records does the export packet announce?
Header offset 2, two bytes, big-endian.
00 04 = 4. The packet is 24 + 4 × 48 = 216 bytes long, which matches.
How many bytes did the client send in flow record 4?
Record offset 20 (+14), four bytes.
05 49 EF 08 = 88,731,400 bytes (IP layer, client → server only). What came back is
in a separate record, not shown in this packet.
Records 1 and 2 are the two directions of the same web request. How many IP bytes did the connection carry in total?
Add the byte counters of both records.
340 + 294 = 634 bytes. Switch the flow builder to "bidirectional": the HTTP connection on port 51514 shows the same numbers as originator and responder bytes, because these records describe the sample capture.
Record 4's TCP flags are 0x1A (SYN, ACK, PSH, no FIN or RST). What does that tell you?
The flags are OR-ed over all packets of the record.
There was a handshake (SYN, ACK) and data (PSH), but no FIN or RST yet: the connection was still open. The router exported it because of a timeout, so the transfer may continue in later records.
These are the 24 header bytes. Edit them and watch the decoded header:
- Set the sampling field (the last two bytes) to
40 64. What do you now have to do with every byte and packet counter in the records? - Change the uptime (bytes 4–7) to
00 37 0E 80, i.e. 2 s longer. By how much do the real start times of all records move?