Table of Contents
- Parsers
- src/parsers/args_parser.c
- init_parser_t
- print_help
- open_save_file_err
- open_save_file
- parse_version
- parse_i_list
- parse_arg
- parse_args
- src/parsers/classify.c
- src/parsers/filter_args.c
- filter_args_free
- filter_args_add
- pattern_to_arg
- filter_args_from_text
- filter_text_end
- find_end
- append_token
- collect_filter_text
- parse_filter_option
- src/parsers/host_parsers.c
- host_char_ok
- dns_read_name
- dns_skip_questions
- dns_learn
- sni_from_extension
- skip_field
- sni_from_client_hello
- sni_learn
- hosts_learn
- src/parsers/parse_l7.c
- src/parsers/parse_link.c
- src/parsers/parse_proto.c
- src/parsers/parse_transport.c
- src/parsers/quic.c
- src/parsers/quic_crypto.c
- src/parsers/quic_flows.c
- src/parsers/quic_frames.c
- src/parsers/raw_to_f.c
Parsers
The command line, and the decoding of frames: link, network, transport, the application facts (DNS, ICMP, HTTP) and payload classes, then DNS, TLS and QUIC for hostnames.
Generated by make docs from the source and GCC's call graph. Back to the Function explorer.
src/parsers/args_parser.c
The command line: each option into parser_t (-I / -O files opened here), and the help
init_parser_t
void init_parser_t(netotter_t *netotter)
src/parsers/args_parser.c:19 · non-static · both builds
Called by: netotter_new
print_help
static void print_help()
src/parsers/args_parser.c:33 · static · both builds
Called by: parse_arg
Calls: my_putstr
open_save_file_err
int open_save_file_err(char flag, int1 out, parser_t *args, int1 filter_flag, int *fd, char *path)
src/parsers/args_parser.c:93 · non-static · both builds
Called by: open_save_file
Calls: my_putstr
open_save_file
static int open_save_file(char *path, int *fd, char flag, parser_t *args)
src/parsers/args_parser.c:116 · static · both builds
Opens the file given to -I (read) or -O / -o (write, see save_open), flag being the option's letter. -O and -o share fd_out: only one of them can be given. 0 on success, the error code otherwise.
Called by: parse_arg
Calls: open_save_file_err, save_open, my_putstr
Library and system calls: _errno, fstat, open, strerror
parse_version
static void parse_version()
src/parsers/args_parser.c:145 · static · both builds
Called by: parse_arg
Calls: my_putunbr, my_putstr
parse_i_list
static int parse_i_list(netotter_t *netotter, char ***ptr)
src/parsers/args_parser.c:152 · static · both builds
Called by: parse_arg
Calls: my_putstr, my_strlen, my_strcpy
Library and system calls: malloc
parse_arg
int parse_arg(netotter_t *netotter, char* arg, char ***ptr)
src/parsers/args_parser.c:171 · non-static · both builds
Called by: parse_args
Calls: print_help, open_save_file, parse_version, parse_i_list, parse_filter_option, anom_trusted_load, my_putstr
parse_args
int parse_args(netotter_t *netotter, char **av)
src/parsers/args_parser.c:243 · non-static · both builds
Called by: netotter
Calls: parse_arg, my_putstr, my_strlen, same_file, same_file
src/parsers/classify.c
What a packet's application data looks like, whatever its port
starts_with
static int starts_with(const uint8_t *d, int len, const char *text)
src/parsers/classify.c:21 · static · both builds
Called by: is_http, mail_or_ftp, classify_payload
Library and system calls: memcmp, strlen
contains
static int contains(const uint8_t *d, int len, const char *text)
src/parsers/classify.c:29 · static · both builds
1 if text appears in the first len bytes
Called by: mail_or_ftp
Library and system calls: memcmp, strlen
is_http
static int is_http(const uint8_t *d, int len)
src/parsers/classify.c:39 · static · both builds
Called by: classify_payload
Calls: starts_with
is_dns
static int is_dns(const uint8_t *d, int len)
src/parsers/classify.c:53 · static · both builds
A DNS header with a sane question count and a readable first name
Called by: classify_payload
Calls: dns_read_name, read_u16
is_quic
static int is_quic(const uint8_t *d, int len)
src/parsers/classify.c:68 · static · both builds
QUIC long header: v1, v2, or version negotiation (0)
Called by: classify_payload
is_ntp
static int is_ntp(const uint8_t *d, int len)
src/parsers/classify.c:78 · static · both builds
Called by: classify_payload
mail_or_ftp
static int mail_or_ftp(const uint8_t *d, int len)
src/parsers/classify.c:88 · static · both builds
The SMTP / FTP / plain "220 " greetings, and their commands
Called by: classify_payload
Calls: starts_with, contains
ln
static double ln(double x)
src/parsers/classify.c:107 · static · both builds
ln(x) for x > 0, without libm: x = m * 2^e with m in [1, 2), then ln(m) = 2 atanh((m - 1) / (m + 1)) as a series
Called by: by_content
by_content
static int by_content(const uint8_t *d, int len)
src/parsers/classify.c:135 · static · both builds
Text, high entropy (encrypted, compressed) or plain binary
Called by: classify_payload
Calls: ln
Library and system calls: memset
classify_payload
int classify_payload(const uint8_t *d, int len, int1 udp)
src/parsers/classify.c:160 · non-static · both builds
What len bytes of application data look like (enum PAYLOAD_CLASS), udp set for a UDP datagram (src/parsers/classify.c) (from
includes/parsers.h)
Called by: parse_l7
Calls: starts_with, is_http, is_dns, is_quic, is_ntp, mail_or_ftp, by_content, read_u16
Library and system calls: memcmp
src/parsers/filter_args.c
Reads the -f / -F filters (<FILTER> <ARGUMENT> ,) into the raw filter list of parser_t
filter_args_free
void filter_args_free(filter_arg_t *list)
src/parsers/filter_args.c:13 · non-static · both builds
Called by: netotter_delete, apply_typed_filters, filters_command, filter_args_add, filter_args_from_text
Library and system calls: free
filter_args_add
static int filter_args_add(filter_arg_t **list, const char *name, const char *arg)
src/parsers/filter_args.c:28 · static · both builds
Appends a copy of name and arg at the end of list. 0 on success, 1 if an allocation fails.
Called by: pattern_to_arg
Calls: filter_args_free, str_dup
Library and system calls: malloc
pattern_to_arg
static int pattern_to_arg(filter_arg_t **list, char *pattern)
src/parsers/filter_args.c:50 · static · both builds
One pattern, "<FILTER> <ARGUMENT>" (extra spaces allowed). 1 if it was added, 0 if it's empty, -1 if it's malformed (printed on stderr).
Called by: filter_args_from_text
Calls: filter_args_add, my_putstr, my_strtok, tab_free
filter_args_from_text
int filter_args_from_text(filter_arg_t **list, char *text, int max)
src/parsers/filter_args.c:71 · non-static · both builds
Filters as typed (src/parsers/filter_args.c). The text holds patterns "<FILTER> <ARGUMENT>" separated by ',', empty patterns are skipped. They're appended to list when every pattern is well formed and there are at most max of them (0: no limit). Returns how many were added, -1 on error (printed on stderr, nothing added). (from
includes/parsers.h)
Called by: filter_command, filters_command, parse_filter_option
Calls: filter_args_free, pattern_to_arg, my_putstr, my_strtok, tab_free
filter_text_end
int filter_text_end(const char *text)
src/parsers/filter_args.c:99 · non-static · both builds
Where the text's list ends: the index of the first empty pattern's ',' (a ',' with only spaces since the start or the previous ','), -1 if there is none. (from
includes/parsers.h)
Called by: filters_command
find_end
static int find_end(const char *token, int1 list, int1 *empty)
src/parsers/filter_args.c:119 · static · both builds
Scans one argv token for the end marker: the first FILTER_SEP for -f (list = 0), an empty pattern (FILTER_SEP with only spaces since the previous one) for -F. *empty tracks that between tokens. 1 when the marker ends the token, 0 if it's not there yet, -1 if text follows it. returns pos of first FILTER_SEP, if spaces before while 'F' (int1 list)
Called by: collect_filter_text
append_token
static int append_token(char **text, int *len, const char *token)
src/parsers/filter_args.c:134 · static · both builds
Appends token and a space to *text. 0 on success, 1 if the allocation fails.
Called by: collect_filter_text
Calls: my_strlen, my_strcpy
Library and system calls: realloc
collect_filter_text
static char *collect_filter_text(char ***ptr, int1 list)
src/parsers/filter_args.c:151 · static · both builds
Joins the argv tokens after -f / -F (moving *ptr) up to the end marker. Allocated, NULL if argv runs out first or text follows the marker.
Called by: parse_filter_option
Calls: find_end, append_token
Library and system calls: free
parse_filter_option
int parse_filter_option(parser_t *args, char ***ptr, int1 list)
src/parsers/filter_args.c:173 · non-static · both builds
-f (list = 0) / -F (list = 1) and their patterns, *ptr is moved past them. 0 on success, the error code otherwise. (from
includes/parsers.h)
Called by: parse_arg
Calls: filter_args_from_text, collect_filter_text, my_putstr
Library and system calls: free
src/parsers/host_parsers.c
Passive hostname learning: DNS answers and TLS ClientHello SNI (QUIC Initial packets in quic.c)
host_char_ok
static int host_char_ok(uint8_t c)
src/parsers/host_parsers.c:15 · static · both builds
Names are printed to the terminal: only printable ASCII is kept, so a crafted packet can't send escape sequences. 1 if c can be kept.
Called by: dns_read_name, sni_from_extension
dns_read_name
int dns_read_name(const uint8_t *msg, int len, int off, char *out)
src/parsers/host_parsers.c:20 · non-static · both builds
Reads the DNS name at off in msg (len bytes) into out (dotted, at most HOST_NAME_MAX_LEN chars, printable ASCII only), following compression pointers. Returns the offset right after the name where it started, -1 if it's malformed. (from
includes/hosts.h)
Called by: is_dns, dns_skip_questions, dns_learn, parse_dns, print_qname, ptr_answer_name
Calls: host_char_ok
dns_skip_questions
static int dns_skip_questions(const uint8_t *msg, int len, int count, char *qname)
src/parsers/host_parsers.c:62 · static · both builds
Skips the question entries: returns the offset of the answers, -1 if they're malformed. The first question's name goes to qname.
Called by: dns_learn
Calls: dns_read_name
dns_learn
int dns_learn(hostmap_t *map, const uint8_t *msg, int len)
src/parsers/host_parsers.c:78 · non-static · both builds
The parsers alone, on a transport payload (UDP payload without its header for DNS, TCP payload after its header for TLS). Return how many names they learned. (from
includes/hosts.h)
Called by: hosts_learn
Calls: dns_read_name, dns_skip_questions, hostmap_set, get16
sni_from_extension
static int sni_from_extension(hostmap_t *map, const uint8_t *ext, int len, int1 v6, const uint8_t *ip_d)
src/parsers/host_parsers.c:118 · static · both builds
The server_name extension body (len bytes): maps ip_d to its host name. 1 if it learned one.
Called by: sni_from_client_hello
Calls: host_char_ok, hostmap_set, get16
skip_field
static int skip_field(const uint8_t *data, int end, int *off, int size)
src/parsers/host_parsers.c:147 · static · both builds
Skips one length-prefixed field (prefix of size bytes) at *off. 0 on success, 1 if it goes past end.
Called by: sni_from_client_hello
Calls: get16
sni_from_client_hello
int sni_from_client_hello(hostmap_t *map, const uint8_t *data, int len, int1 v6, const uint8_t *ip_d)
src/parsers/host_parsers.c:158 · non-static · both builds
The same from the ClientHello handshake message itself (type, u24 length, body), without the TLS record header, as QUIC carries it (from
includes/hosts.h)
Called by: sni_learn, flow_finish
Calls: sni_from_extension, skip_field, get16
sni_learn
int sni_learn(hostmap_t *map, const uint8_t *data, int len, int1 v6, const uint8_t *ip_d)
src/parsers/host_parsers.c:192 · non-static · both builds
Called by: hosts_learn
Calls: sni_from_client_hello, get16
hosts_learn
void hosts_learn(hostmap_t *map, fpacket_t *packet)
src/parsers/host_parsers.c:207 · non-static · both builds
src/parsers/host_parsers.c Learns from one packet: DNS answers (UDP from port 53) map their A / AAAA addresses to the question name, a TLS ClientHello (over TCP, or in QUIC Initial packets) maps the destination IP to its SNI. Reads only, every access bounds-checked. (from
includes/hosts.h)
Called by: process_packet
Calls: dns_learn, sni_learn, quic_learn
src/parsers/parse_l7.c
What a packet says at the application layer, read while its payload is plain: DNS header and question, ICMP type and the packet an error is about, HTTP request method or response status, and the class of its data (classify.c)
l7_new
static l7_info_t *l7_new(fpacket_t *fpacket, enum L7_KIND kind)
src/parsers/parse_l7.c:27 · static · both builds
Called by: parse_dns, parse_icmp, parse_http
Library and system calls: calloc
lower
static char lower(char c)
src/parsers/parse_l7.c:38 · static · both builds
Called by: qname_facts
qname_facts
static void qname_facts(l7_info_t *l7, char *name)
src/parsers/parse_l7.c:44 · static · both builds
Length, longest label and hashes of a question name
Called by: parse_dns
Calls: lower, my_strlen, fnv1a
parse_dns
static void parse_dns(fpacket_t *fpacket, const uint8_t *msg, int len)
src/parsers/parse_l7.c:70 · static · both builds
A DNS message (len bytes): header, then the first question
Called by: parse_l7
Calls: dns_read_name, l7_new, qname_facts, read_u16
parse_inner
static void parse_inner(l7_info_t *l7, const uint8_t *ip, int len)
src/parsers/parse_l7.c:95 · static · both builds
The IP header (and its ports) quoted by an ICMP error
Called by: parse_icmp
Calls: read_u16
parse_icmp
static void parse_icmp(fpacket_t *fpacket, const uint8_t *h, int len, int1 v6)
src/parsers/parse_l7.c:124 · static · both builds
Called by: parse_l7
Calls: l7_new, parse_inner
parse_http
static void parse_http(fpacket_t *fpacket, const uint8_t *data, int len)
src/parsers/parse_l7.c:142 · static · both builds
"GET /..." or "HTTP/1.1 404 ..." at the start of a TCP segment
Called by: parse_l7
Calls: l7_new, my_strlen
Library and system calls: memcmp
parse_l7
void parse_l7(fpacket_t *fpacket, int l4_proto)
src/parsers/parse_l7.c:178 · non-static · both builds
DNS, ICMP and HTTP facts into fpacket->l7 (src/parsers/parse_l7.c), and the class of its application data (from
includes/parsers.h)
Called by: process_packet
Calls: classify_payload, parse_dns, parse_icmp, parse_http
src/parsers/parse_link.c
The link layer: the Ethernet header, or the EtherType guessed from the IP version on raw-IP links
parse_eth
static int parse_eth(fpacket_t *fpacket, const uint8_t *frame, int len)
src/parsers/parse_link.c:13 · static · both builds
Called by: parse_link
Calls: read_u16
Library and system calls: malloc
parse_link
int parse_link(fpacket_t *fpacket, const uint8_t *frame, int len)
src/parsers/parse_link.c:34 · non-static · both builds
Link layer: decodes it and sets net_proto. Returns the link header length (where the network layer starts), -1 to drop the frame.
Called by: process_packet
Calls: parse_eth
src/parsers/parse_proto.c
The network layer parsers of net_parsers[]: IPv4, IPv6 (and its extension headers) and ARP
parse_ipv4
int parse_ipv4(fpacket_t *fpacket, const uint8_t *ip, int len, net_result_t *res)
src/parsers/parse_proto.c:13 · non-static · both builds
Called by: process_packet, through net_parsers[]
Calls: read_u16
Library and system calls: malloc
skip_ipv6_extensions
static void skip_ipv6_extensions(ipv6_header_t *ipv6, const uint8_t *ext, int len)
src/parsers/parse_proto.c:62 · static · both builds
Fixed IPv6 header only: with extension headers, next_hdr is not a transport protocol and parse_transport() leaves the packet at T_UNK. Skips the extension headers after the fixed IPv6 header (len bytes): Hop-by-Hop, Routing and Destination Options, at most IP6_EXT_MAX, each "next header, length in 8-byte units minus 1". Sets ipv6->upper and ipv6->ext_len; stops at anything else (Fragment included) or at a header that doesn't fit.
Called by: parse_ipv6
parse_ipv6
int parse_ipv6(fpacket_t *fpacket, const uint8_t *ip, int len, net_result_t *res)
src/parsers/parse_proto.c:83 · non-static · both builds
Called by: process_packet, through net_parsers[]
Calls: skip_ipv6_extensions, read_u16, read_u32
Library and system calls: malloc
parse_arp
int parse_arp(fpacket_t *fpacket, const uint8_t *arp, int len, net_result_t *res)
src/parsers/parse_proto.c:117 · non-static · both builds
ARP for IPv4 over Ethernet (every ARP on Ethernet and Wi-Fi). Other hardware or protocol types aren't decoded.
Called by: process_packet, through net_parsers[]
Calls: read_u16
Library and system calls: malloc
src/parsers/parse_transport.c
The transport layer: TCP and UDP headers, and IGMP / MLD (multicast group membership)
parse_mcast_records
static void parse_mcast_records(mcast_header_t *m, const uint8_t *h, int len, int off, int addr_len)
src/parsers/parse_transport.c:17 · static · both builds
The group records of an IGMPv3 / MLDv2 report, from h[off] (len bytes in all): type, aux data length (in 4-byte words), source count, group (addr_len bytes), then the sources and aux data, skipped. Records are walked while they fit, the first MCAST_MAX_RECORDS are kept.
Called by: parse_igmp, parse_mld
Calls: read_u16
mcast_new
static mcast_header_t *mcast_new(fpacket_t *fpacket, int1 v6)
src/parsers/parse_transport.c:37 · static · both builds
A new zeroed mcast header for the packet, NULL if the allocation fails
Called by: parse_igmp, parse_mld
Library and system calls: malloc, memset
parse_tcph
static int parse_tcph(fpacket_t *fpacket)
src/parsers/parse_transport.c:51 · static · both builds
Decodes the TCP header at the start of the payload. 0 on success, 1 if the payload is too short or malformed.
Called by: parse_transport
Calls: read_u16, read_u32
Library and system calls: malloc
parse_udph
static int parse_udph(fpacket_t *fpacket)
src/parsers/parse_transport.c:84 · static · both builds
Decodes the UDP header at the start of the payload. 0 on success, 1 if the payload is too short.
Called by: parse_transport
Calls: read_u16
Library and system calls: malloc
parse_igmp
static void parse_igmp(fpacket_t *fpacket)
src/parsers/parse_transport.c:106 · static · both builds
IGMP (IPv4 only): queries, v1/v2 reports and leaves, v3 reports
Called by: parse_transport
Calls: parse_mcast_records, mcast_new, read_u16
parse_mld
static void parse_mld(fpacket_t *fpacket)
src/parsers/parse_transport.c:144 · static · both builds
MLD (IPv6, ICMPv6 types 130 to 132 and 143; other ICMPv6 untouched)
Called by: parse_transport
Calls: parse_mcast_records, mcast_new, read_u16
parse_transport
void parse_transport(fpacket_t *fpacket, int l4_proto)
src/parsers/parse_transport.c:181 · non-static · both builds
Transport layer, decoded from the start of the payload. A header that can't be decoded leaves ptype at T_UNK, the packet is still kept.
Called by: process_packet
Calls: parse_tcph, parse_udph, parse_igmp, parse_mld
src/parsers/quic.c
QUIC Initial packets (HTTP/3): their keys come from public values (RFC 9001 5.2, RFC 9369), so the ClientHello they carry can be decrypted passively and its SNI learned. This file walks the datagram's packets; keys and decryption are in quic_crypto.c, frames in quic_frames.c, ClientHello reassembly in quic_flows.c
quic_initial
static int quic_initial(hostmap_t *map, const uint8_t *pkt, int pn_off, int length, uint32_t version, const quic_addr_t *addr)
src/parsers/quic.c:19 · static · both builds
Decrypts one Initial packet (pkt, pn_off + length bytes, the packet number at pn_off) and feeds its CRYPTO frames to its flow. 1 if it learned a name.
Called by: quic_packet
Calls: initial_keys, hp_mask, unmask_header, gcm_open, flow_finish, read_frames
Library and system calls: free, malloc, memcpy
packet_type
static int packet_type(uint8_t first, uint32_t version)
src/parsers/quic.c:56 · static · both builds
The long header packet type, as QUIC v1 numbers it (QUIC_TYPE_*): v2 numbers Initial 1, 0-RTT 2, Handshake 3 and Retry 0
Called by: quic_packet
skip_cid
static int skip_cid(const uint8_t *pkt, int len, int *off)
src/parsers/quic.c:65 · static · both builds
Skips a connection id: u8 length (at most QUIC_CID_MAX), then the id. 0 on success, 1 if it's too long or goes past len.
Called by: quic_packet
quic_packet
static int quic_packet(hostmap_t *map, const uint8_t *pkt, int len, const quic_addr_t *addr, int *learned)
src/parsers/quic.c:78 · static · both builds
One long-header packet at the start of pkt: decrypts it if it's a v1 / v2 Initial. Returns its length (coalesced packets follow it), 0 to stop reading the datagram.
Called by: quic_learn
Calls: quic_initial, packet_type, skip_cid, read_length, get32
quic_learn
int quic_learn(hostmap_t *map, const uint8_t *data, int len, int1 v6, const uint8_t *ip_s, const uint8_t *ip_d)
src/parsers/quic.c:112 · non-static · both builds
src/parsers/quic.c Decrypts the QUIC v1 / v2 Initial packets of a UDP payload (their keys only depend on public values) and collects their CRYPTO frames; once a flow's ClientHello is complete, maps ip_d to its SNI. 1 if it learned a name. (from
includes/hosts.h)
Called by: hosts_learn
Calls: quic_packet
src/parsers/quic_crypto.c
QUIC Initial keys (HKDF from the version salt and the DCID), header protection and AES-128-GCM decryption
expand_label
static int expand_label(const uint8_t *secret, const char *label, uint8_t *out, int out_len)
src/parsers/quic_crypto.c:17 · static · both builds
TLS 1.3 HKDF-Expand-Label with an empty context. Every output here is at most one SHA-256 block, so the expansion is a single HMAC.
Called by: initial_keys
Calls: my_strlen
Library and system calls: EVP_sha256, HMAC, memcpy
initial_keys
int initial_keys(uint32_t version, const uint8_t *dcid, int dcid_len, quic_keys_t *keys)
src/parsers/quic_crypto.c:44 · non-static · both builds
The client's Initial keys for this DCID. 0 on success.
Called by: quic_initial
Calls: expand_label
Library and system calls: EVP_sha256, HMAC
hp_mask
int hp_mask(const uint8_t *hp, const uint8_t *sample, uint8_t *mask)
src/parsers/quic_crypto.c:68 · non-static · both builds
Header protection mask: AES-128-ECB of the sample. 0 on success.
Called by: quic_initial
Library and system calls: EVP_CIPHER_CTX_free, EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_set_padding, EVP_EncryptInit_ex, EVP_EncryptUpdate, EVP_aes_128_ecb
unmask_header
int unmask_header(uint8_t *buf, int pn_off, const uint8_t *mask, uint64_t *pn)
src/parsers/quic_crypto.c:87 · non-static · both builds
Removes the header protection from buf, a copy of the header up to the longest packet number: the low bits of byte 0 (reserved bits, packet number length), then the packet number, read into *pn. Returns the packet number's length (1 to 4).
Called by: quic_initial
gcm_nonce
static void gcm_nonce(const quic_keys_t *keys, uint64_t pn, uint8_t *nonce)
src/parsers/quic_crypto.c:104 · static · both builds
The packet's nonce: the IV with the packet number (big-endian) XORed into its last bytes
Called by: gcm_open
Library and system calls: memcpy
gcm_open
int gcm_open(const quic_keys_t *keys, uint64_t pn, const uint8_t *aad, int aad_len, const uint8_t *in, int in_len, uint8_t *out)
src/parsers/quic_crypto.c:114 · non-static · both builds
AES-128-GCM decryption of in (in_len bytes, tag included) into out. The plaintext length, -1 if the tag doesn't match: then it wasn't a QUIC Initial packet after all.
Called by: quic_initial
Calls: gcm_nonce
Library and system calls: EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX_free, EVP_CIPHER_CTX_new, EVP_DecryptFinal_ex, EVP_DecryptInit_ex, EVP_DecryptUpdate, EVP_aes_128_gcm
src/parsers/quic_flows.c
QUIC flows: the ClientHello of each (addresses, DCID), rebuilt from its CRYPTO frames, then handed to the SNI parser
flow_unlink
static void flow_unlink(hostmap_t *map, quic_flow_t *flow)
src/parsers/quic_flows.c:12 · static · both builds
Called by: flow_get, flow_finish
Library and system calls: free
flow_matches
static int flow_matches(const quic_flow_t *flow, const quic_initial_t *in)
src/parsers/quic_flows.c:27 · static · both builds
1 if flow collects the ClientHello of this packet's addresses and DCID
Called by: flow_get
Library and system calls: memcmp
flow_get
quic_flow_t *flow_get(quic_initial_t *in)
src/parsers/quic_flows.c:43 · non-static · both builds
The flow of this packet's addresses and DCID, created if it's new (the oldest one dropped when there are too many). NULL if the allocation fails.
Called by: read_crypto
Calls: flow_unlink, flow_matches
Library and system calls: calloc, memcpy
flow_add
int flow_add(quic_flow_t *flow, uint64_t offset, const uint8_t *data, uint64_t len)
src/parsers/quic_flows.c:72 · non-static · both builds
Stores one CRYPTO frame. 1 if it goes past the buffer.
Called by: read_crypto
Library and system calls: memcpy
flow_has
static int flow_has(const quic_flow_t *flow, int k)
src/parsers/quic_flows.c:84 · static · both builds
1 if byte k of the ClientHello was received
Called by: flow_complete
flow_complete
static int flow_complete(const quic_flow_t *flow)
src/parsers/quic_flows.c:91 · static · both builds
The ClientHello's full length once every byte of it is in, 0 while some are missing, -1 if it can't fit the buffer
Called by: flow_finish
Calls: flow_has
flow_finish
int flow_finish(quic_initial_t *in, int drop)
src/parsers/quic_flows.c:112 · non-static · both builds
After a packet that fed the flow: once its ClientHello is complete, learns the SNI. A complete flow, or one that can't be (drop), is freed. 1 if it learned a name.
Called by: quic_initial
Calls: sni_from_client_hello, flow_unlink, flow_complete
quic_flows_free
void quic_flows_free(hostmap_t *map)
src/parsers/quic_flows.c:125 · non-static · both builds
Frees the flows still waiting for the rest of their ClientHello (from
includes/hosts.h)
Called by: hostmap_free
Library and system calls: free
src/parsers/quic_frames.c
QUIC varints and the frames of a decrypted Initial payload: CRYPTO frames go to the packet's flow, the rest is skipped
read_varint
static int read_varint(const uint8_t *data, int len, int *off, uint64_t *value)
src/parsers/quic_frames.c:12 · static · both builds
A variable-length integer at *off (2-bit size prefix). 0 on success, 1 if it goes past len.
Called by: read_length, skip_varints, skip_ack, read_crypto, read_frames
read_length
int read_length(const uint8_t *data, int len, int *off, uint64_t *value)
src/parsers/quic_frames.c:31 · non-static · both builds
A varint length followed by that many bytes, which must fit in len. 0 on success, 1 otherwise.
Called by: quic_packet, read_crypto
Calls: read_varint
skip_varints
static int skip_varints(const uint8_t *data, int len, int *off, uint64_t count)
src/parsers/quic_frames.c:40 · static · both builds
Skips count varints. 0 on success, 1 if one goes past len.
Called by: skip_ack
Calls: read_varint
skip_ack
static int skip_ack(const uint8_t *data, int len, int *off, int1 ecn)
src/parsers/quic_frames.c:52 · static · both builds
Skips the body of an ACK frame (the type already read). 0 on success.
Called by: read_frames
Calls: read_varint, skip_varints
read_crypto
static int read_crypto(quic_initial_t *in, const uint8_t *data, int len, int *off)
src/parsers/quic_frames.c:71 · static · both builds
One CRYPTO frame (the type already read): offset, length, data, stored in the flow (created at the first one). 0 on success, -1 to stop reading the frames, 1 if the flow has to be dropped.
Called by: read_frames
Calls: flow_get, flow_add, read_varint, read_length
read_frames
int read_frames(quic_initial_t *in, const uint8_t *data, int len)
src/parsers/quic_frames.c:93 · non-static · both builds
Reads the frames of a decrypted Initial payload into the flow. 1 if the flow has to be dropped.
Called by: quic_initial
Calls: read_varint, skip_ack, read_crypto
src/parsers/raw_to_f.c
Turns the raw frames of the queue into packets (raw to formatted), layer by layer
read_u16
uint16_t read_u16(const uint8_t *p)
src/parsers/raw_to_f.c:18 · non-static · both builds
Big-endian (network order) reads (from
includes/network.h)
Called by: is_dns, classify_payload, parse_dns, parse_inner, parse_eth, parse_ipv4, parse_ipv6, parse_arp, parse_mcast_records, parse_tcph, parse_udph, parse_igmp, parse_mld
read_u32
uint32_t read_u32(const uint8_t *p)
src/parsers/raw_to_f.c:23 · non-static · both builds
Called by: parse_ipv6, parse_tcph
find_net_parser
static net_parser_t find_net_parser(uint16_t ethertype)
src/parsers/raw_to_f.c:29 · static · both builds
Called by: process_packet
process_packet
static fpacket_t *process_packet(netotter_t *netotter, queue_t *q)
src/parsers/raw_to_f.c:41 · static · both builds
Decodes one frame layer by layer, learns the hostnames it carries, then stores its payload (compressed, out of RAM). NULL if it's dropped.
Called by: raw_to_f
Calls: hosts_learn, parse_l7, parse_link, parse_ipv4, parse_ipv6, parse_arp, parse_transport, find_net_parser, fpacket_new, fpacket_set_payload, fpacket_delete, store_payload
Library and system calls: (through net_parsers[])
raw_to_f
void raw_to_f(netotter_t *netotter)
src/parsers/raw_to_f.c:87 · non-static · both builds
Called by: run_cli, run_interactive
Calls: process_packet, fpacket_delete, packets_add, store_flush, queue_purge
User guide
- Overview
- Installation
- Getting started
- Command-line options
- Interactive commands
- Display filters
- Analysis view
- Reverse DNS and privacy
- Anomaly detection
- Save files
- Memory and limits
- Troubleshooting
Developer documentation
- Overview
- Building
- Architecture
- OS backends
- Packet parsing
- Packet storage
- Save format
- Hostname learning
- Reverse DNS internals
- Filters and analysis internals
- Anomaly lab
- Coding conventions
- Function explorer
Learning