3 Functions Linux backend
Watersrc-stack edited this page 2026-10-14 04:00:21 +02:00

Linux backend

The common_lib.h functions on Linux: AF_PACKET sockets and their TPACKET_V3 ring, getifaddrs, poll, resolv.conf.

Generated by make docs from the source and GCC's call graph. Back to the Function explorer.

libs/linux/linux_addresses.c

The machine's own addresses (the 'me' filter), from getifaddrs()

known

static int known(local_addr_t *list, const char *ifname, int1 v6, const uint8_t *ip)

libs/linux/linux_addresses.c:15 · static · linux build only

1 if list already holds that address on that interface

Called by: add
Library and system calls: memcmp, strcmp

add

static int add(local_addr_t **list, const char *ifname, int1 v6, const uint8_t *ip)

libs/linux/linux_addresses.c:26 · static · linux build only

Appends one address. 1 if it was added.

Called by: local_addresses_refresh
Calls: known
Library and system calls: malloc, memcpy, memset, strncpy

local_addresses_refresh

int local_addresses_refresh(lib_common_t *common_lib, local_addr_t **list)

libs/linux/linux_addresses.c:46 · non-static · linux build only

Appends the interfaces' current IPv4 / IPv6 addresses that aren't in *list yet (the 'me' filter): nothing is ever removed, an address the machine had stays its own. Returns how many were added. (from includes/common_lib.h)

Called by: local_refresh
Calls: add
Library and system calls: freeifaddrs, getifaddrs

libs/linux/linux_common_functions.c

The common lib functions (common_lib.h) for Linux

init_common_struct

lib_common_t *init_common_struct()

libs/linux/linux_common_functions.c:15 · non-static · linux build only

Starts the backend: sets lib_name ("Linux" / "Windows") and lists the interfaces, all disabled (from includes/common_lib.h)

Called by: netotter
Calls: my_strncpy, set_interfaces, lib_linux_init
Library and system calls: malloc

common_lib_terminate

int1 common_lib_terminate(lib_common_t *common_lib)

libs/linux/linux_common_functions.c:27 · non-static · linux build only

Closes every capture and the resolver socket, then frees the backend and its interface list. 1 if common_lib is NULL, 0 otherwise. (from includes/common_lib.h)

Called by: netotter
Calls: if_tab_delete, lib_linux_destroy, close_all_sockets, resolver_close
Library and system calls: free

tick

void tick(lib_common_t *common_lib, queue_t **q)

libs/linux/linux_common_functions.c:42 · non-static · linux build only

Appends the frames waiting on every enabled interface to *q, without blocking (at most NW_TICK_MAX per interface) (from includes/common_lib.h)

Called by: run_cli, run_interactive
Calls: nw_tick

disable_all

int disable_all(lib_common_t *common_lib)

libs/linux/linux_common_functions.c:50 · non-static · linux build only

Stops listening on every enabled interface, returns how many were (from includes/common_lib.h)

Called by: handle_key, capture_full_check
Calls: close_all_sockets

if_disable

static enum IFN_STATE if_disable(interface_t *itrf)

libs/linux/linux_common_functions.c:63 · static · linux build only

Called by: toggle_ifname
Calls: nw_close_socket

if_enable

static enum IFN_STATE if_enable(interface_t *itrf)

libs/linux/linux_common_functions.c:71 · static · linux build only

Called by: toggle_ifname
Calls: nw_open_socket

toggle_ifname

enum IFN_STATE toggle_ifname(lib_common_t *common_lib, int if_id)

libs/linux/linux_common_functions.c:79 · non-static · linux build only

Starts or stops the capture on interface if_id (the number -l shows). The interface's new state, IFN_UNK if there's no such interface. (from includes/common_lib.h)

Called by: enable_from_list, handle_key
Calls: my_write, if_disable, if_enable

get_ifname_state

enum IFN_STATE get_ifname_state(lib_common_t *common_lib, int if_id)

libs/linux/linux_common_functions.c:102 · non-static · linux build only

The state of interface if_id, IFN_UNK if there's no such interface (from includes/common_lib.h)

Called by: enable_from_list
Calls: my_write

libs/linux/linux_input.c

Waiting for the interactive mode's input on stdin

stdin_wait

int stdin_wait(lib_common_t *common_lib, int timeout_ms)

libs/linux/linux_input.c:10 · non-static · linux build only

Waits up to timeout_ms for the interactive mode's input on stdin: 1 when a read won't block (a typed line, or the end of stdin), 0 on timeout, -1 with errno set on error (EINTR when a signal interrupted the wait). (from includes/common_lib.h)

Called by: run_interactive
Library and system calls: poll

libs/linux/linux_lib.c

Main file for the linux-specific lib: the interface list (if_nameindex), plus same_file, my_usleep, local_date, term_colors and cache_file_path

get_iftype

static enum PACKET_SRC get_iftype(const char *ifname)

libs/linux/linux_lib.c:24 · static · linux build only

PT_WIFI when the interface answers the wireless extensions ioctl

Called by: set_interfaces
Calls: my_putstr
Library and system calls: close, ioctl, memset, socket, strncpy

set_interfaces

interface_t **set_interfaces()

libs/linux/linux_lib.c:41 · non-static · linux build only

Called by: init_common_struct
Calls: if_tab_append, get_iftype
Library and system calls: if_freenameindex, if_nameindex, malloc

lib_linux_init

lib_linux_t *lib_linux_init()

libs/linux/linux_lib.c:60 · non-static · linux build only

Called by: init_common_struct
Library and system calls: malloc

lib_linux_destroy

void lib_linux_destroy(lib_linux_t *lib_linux)

libs/linux/linux_lib.c:69 · non-static · linux build only

Called by: common_lib_terminate
Library and system calls: free

close_all_sockets

void close_all_sockets(interface_t **itrfs)

libs/linux/linux_lib.c:76 · non-static · linux build only

Called by: common_lib_terminate, disable_all
Calls: nw_close_socket

same_file

int same_file(int fd_a, int fd_b)

libs/linux/linux_lib.c:84 · non-static · linux build only

1 when the open files fd_a and fd_b are the same file (-I and -O), 0 otherwise or if one of them is -1. No common_lib: the arguments are parsed before the backend starts. (from includes/common_lib.h)

Called by: parse_args
Library and system calls: fstat

my_usleep

void my_usleep(uint32_t usec)

libs/linux/linux_lib.c:95 · non-static · linux build only

Sleeps usec microseconds (usleep is obsolete in POSIX and deprecated on some Windows toolchains). A signal can end it early on Linux. No common_lib: it needs no backend state. (from includes/common_lib.h)

Called by: run_cli
Library and system calls: nanosleep

local_date

int local_date(uint64_t sec, date_t *out)

libs/linux/linux_lib.c:106 · non-static · linux build only

mkdir that accepts an existing directory. 0 on success.

Called by: print_capture_time
Library and system calls: localtime_r

make_dir

static int make_dir(const char *path)

libs/linux/linux_lib.c:122 · static · linux build only

Called by: cache_file_path
Library and system calls: mkdir

term_colors

int term_colors(void)

libs/linux/linux_lib.c:127 · non-static · linux build only

1 if stdout is a terminal that shows ANSI colors (on Windows, the console's virtual terminal mode is turned on here), 0 otherwise: the alerts are then written in capitals. No lib_common_t. (from includes/common_lib.h)

Called by: colors, print_alert
Library and system calls: getenv, isatty, strcmp

cache_file_path

int cache_file_path(const char *name, char *buf, int size, int1 create)

libs/linux/linux_lib.c:135 · non-static · linux build only

XDG base directories: a relative XDG_CACHE_HOME is invalid, ignored

Called by: cache_create, reverse_cache_load, spool_open
Calls: my_strappend, make_dir
Library and system calls: getenv

libs/linux/linux_network.c

Linux specific packet access: one AF_PACKET socket per enabled interface, read without blocking on each tick through a memory-mapped TPACKET_V3 ring (recvmsg() if the ring can't be set up), with the kernel's drop count reported

nw_ring_open

static nw_ring_t *nw_ring_open(int sock)

libs/linux/linux_network.c:40 · static · linux build only

Maps a TPACKET_V3 ring on the socket. NULL if the kernel refuses (then frames are read with recvmsg, through the socket buffer).

Called by: nw_open_socket
Library and system calls: calloc, free, memset, mmap, setsockopt

nw_ring_close

static void nw_ring_close(nw_ring_t *ring)

libs/linux/linux_network.c:73 · static · linux build only

Called by: nw_close_socket
Library and system calls: free, munmap

nw_open_socket

void nw_open_socket(interface_t *itrf)

libs/linux/linux_network.c:81 · non-static · linux build only

Called by: if_enable
Calls: my_putstr, my_write, nw_ring_open
Library and system calls: bind, close, htons, if_nametoindex, setsockopt, socket

nw_close_socket

void nw_close_socket(interface_t *itrf)

libs/linux/linux_network.c:118 · non-static · linux build only

Called by: if_disable, close_all_sockets
Calls: my_putstr, nw_ring_close
Library and system calls: close

static enum LINK_TYPE nw_link_type(unsigned short hatype)

libs/linux/linux_network.c:130 · static · linux build only

Linux hardware type of the frame's interface -> core link type

Called by: nw_node

nw_node

static queue_t *nw_node(interface_t *itrf, const uint8_t *frame, uint32_t len, unsigned short hatype, uint64_t ts_us)

libs/linux/linux_network.c:141 · static · linux build only

A queue node holding a copy of the frame (at most NW_RECV_BUF bytes)

Called by: nw_recv_one, nw_ring_block
Calls: nw_link_type
Library and system calls: malloc, memcpy

now_us

static uint64_t now_us(void)

libs/linux/linux_network.c:162 · static · linux build only

Now, in microseconds since the Unix epoch

Called by: nw_frame_time
Library and system calls: clock_gettime

nw_frame_time

static uint64_t nw_frame_time(struct msghdr *msg)

libs/linux/linux_network.c:171 · static · linux build only

The kernel receive time (SO_TIMESTAMPNS) of the message, or now

Called by: nw_recv_one
Calls: now_us

nw_recv_one

static queue_t *nw_recv_one(interface_t *itrf, unsigned char *scratch)

libs/linux/linux_network.c:188 · static · linux build only

Without a ring: one frame from the socket buffer, NULL when it's empty

Called by: nw_tick
Calls: my_write, nw_node, nw_frame_time
Library and system calls: recvmsg

nw_ring_block

static uint32_t nw_ring_block(interface_t *itrf, struct tpacket_block_desc *block, queue_t ***tail)

libs/linux/linux_network.c:217 · static · linux build only

The frames of one block the kernel handed over, appended at *tail. Returns how many.

Called by: nw_ring_read
Calls: nw_node

nw_ring_read

static uint32_t nw_ring_read(interface_t *itrf, nw_ring_t *ring, queue_t ***tail)

libs/linux/linux_network.c:243 · static · linux build only

The blocks the kernel handed over, until NW_TICK_MAX frames

Called by: nw_tick
Calls: nw_ring_block

nw_drops

static uint32_t nw_drops(interface_t *itrf)

libs/linux/linux_network.c:266 · static · linux build only

Frames the kernel dropped since the last call (a full ring or buffer: NetOtter didn't read fast enough). Reading the counters resets them.

Called by: nw_tick
Library and system calls: getsockopt, memset

nw_tick_report

static void nw_tick_report(interface_t *itrf, uint32_t fetched, uint32_t dropped)

libs/linux/linux_network.c:287 · static · linux build only

Called by: nw_tick
Calls: my_putunbr, my_strlen, my_write

nw_tick

void nw_tick(interface_t *itrf, queue_t **q)

libs/linux/linux_network.c:303 · non-static · linux build only

Called by: tick
Calls: nw_recv_one, nw_ring_read, nw_drops, nw_tick_report

libs/linux/linux_resolver.c

The UDP socket NetOtter's own reverse DNS lookups go through (online mode only): the system resolver from /etc/resolv.conf

first_nameserver

static int first_nameserver(char *addr, int size)

libs/linux/linux_resolver.c:27 · static · linux build only

The first "nameserver <address>" of resolv.conf into addr (size bytes). 0 on success, -1 if there is none.

Called by: resolver_open
Library and system calls: fclose, fgets, fopen, memcpy, strncmp

connect_resolver

static int connect_resolver(const char *addr)

libs/linux/linux_resolver.c:57 · static · linux build only

A non-blocking UDP socket connected to addr:53 (IPv4 or IPv6), -1 on error

Called by: resolver_open
Library and system calls: close, connect, htons, inet_pton, memset, socket

resolver_open

int resolver_open(lib_common_t *common_lib, char *addr, int size)

libs/linux/linux_resolver.c:85 · non-static · linux build only

The socket NetOtter's own reverse DNS lookups go through (online mode only, see src/analysis/reverse.c). resolver_open connects a non-blocking UDP socket to the system resolver, port 53, and writes the resolver's address to addr (size bytes): 0 on success, -1 if there is none (or the OS backend doesn't support it). Nothing is sent before resolver_send. resolver_recv returns the bytes read, 0 when nothing is waiting, -1 on error. (from includes/common_lib.h)

Called by: open_resolver
Calls: first_nameserver, connect_resolver

resolver_send

int resolver_send(lib_common_t *common_lib, const uint8_t *query, int len)

libs/linux/linux_resolver.c:96 · non-static · linux build only

Called by: send_query
Library and system calls: send

resolver_recv

int resolver_recv(lib_common_t *common_lib, uint8_t *buf, int size)

libs/linux/linux_resolver.c:104 · non-static · linux build only

Called by: reverse_tick
Library and system calls: recv

random_bytes

int random_bytes(lib_common_t *common_lib, void *buf, int len)

libs/linux/linux_resolver.c:117 · non-static · linux build only

Fills buf with len random bytes from the OS (unpredictable, for the DNS query ids). 0 on success, -1 if there's no random source. (from includes/common_lib.h)

Called by: new_query_id, open_resolver
Library and system calls: getrandom

resolver_close

void resolver_close(lib_common_t *common_lib)

libs/linux/linux_resolver.c:134 · non-static · linux build only

Called by: reverse_toggle_online, common_lib_terminate
Library and system calls: close

libs/linux/linux_spool.c

The payload spool on Linux: an unnamed file (O_TMPFILE) in the cache directory, which the kernel deletes when it's closed, even after a crash

open_named

static int open_named(const char *dir)

libs/linux/linux_spool.c:27 · static · linux build only

The fallback: a named file, unlinked right away (left behind only if NetOtter dies between the two calls)

Called by: spool_open
Calls: my_strappend
Library and system calls: mkstemp, unlink

spool_open

spool_t *spool_open(char *dir, int size)

libs/linux/linux_spool.c:42 · non-static · linux build only

Opens it and writes its directory to dir (size bytes). NULL if it can't be created. (from includes/common_lib.h)

Called by: store_init
Calls: cache_file_path, open_named
Library and system calls: free, malloc, open

spool_write_at

int spool_write_at(spool_t *spool, uint64_t off, const uint8_t *buf, uint32_t len)

libs/linux/linux_spool.c:63 · non-static · linux build only

Writes / reads len bytes at offset off. 0 on success, -1 on error. (from includes/common_lib.h)

Called by: store_flush
Library and system calls: pwrite

spool_read_at

int spool_read_at(spool_t *spool, uint64_t off, uint8_t *buf, uint32_t len)

libs/linux/linux_spool.c:81 · non-static · linux build only

Called by: store_stored_bytes
Library and system calls: pread

spool_close

void spool_close(spool_t *spool)

libs/linux/linux_spool.c:98 · non-static · linux build only

Called by: store_free
Library and system calls: close, free