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

Windows backend

The common_lib.h functions on Windows: Npcap loaded at runtime, adapters, Winsock, the console.

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

libs/windows/windows_adapters.c

The network adapters' list (GetAdaptersAddresses) and their names, for the interface list and the own addresses

adapters_get

IP_ADAPTER_ADDRESSES *adapters_get(ULONG flags)

libs/windows/windows_adapters.c:17 · non-static · windows build only

windows_adapters.c: the adapters' list and names, shared by the interface list and the own addresses GetAdaptersAddresses(AF_UNSPEC, flags), allocated (to free), NULL on error (from libs/windows/windows_lib.h)

Called by: local_addresses_refresh, set_interfaces
Library and system calls: GetAdaptersAddresses, free, malloc

adapter_short_name

int adapter_short_name(const IP_ADAPTER_ADDRESSES *adapter, char name[WIN_IFNAME_SIZE])

libs/windows/windows_adapters.c:39 · non-static · windows build only

The adapter's short name (wireless_32768, ethernet_32769, loopback_0), cut to WIN_IFNAME_SIZE - 1 chars. 0 on success, -1 on error. (from libs/windows/windows_lib.h)

Called by: add_adapter, describe
Library and system calls: ConvertInterfaceLuidToNameA, strncpy

append_ascii

static void append_ascii(char *buf, size_t *len, const wchar_t *str)

libs/windows/windows_adapters.c:54 · static · windows build only

Appends str to buf at *len: printable ASCII as is, '?' for the rest (the console isn't UTF-8 by default, and no escape reaches it)

Called by: adapter_desc

adapter_desc

char *adapter_desc(const IP_ADAPTER_ADDRESSES *adapter)

libs/windows/windows_adapters.c:60 · non-static · windows build only

"<friendly name>: <description>", allocated (to free), only printable ASCII ('?' for the rest). NULL on error. (from libs/windows/windows_lib.h)

Called by: describe
Calls: append_ascii
Library and system calls: malloc, wcslen

libs/windows/windows_addresses.c

The machine's own addresses (the 'me' filter), from GetAdaptersAddresses(), named like the interface list

known

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

libs/windows/windows_addresses.c:13 · static · windows 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/windows/windows_addresses.c:24 · static · windows build only

Appends one address. 1 if it was added.

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

add_adapter

static int add_adapter(local_addr_t **list, IP_ADAPTER_ADDRESSES *adapter)

libs/windows/windows_addresses.c:45 · static · windows build only

Every unicast address of one adapter

Called by: local_addresses_refresh
Calls: adapter_short_name, add

local_addresses_refresh

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

libs/windows/windows_addresses.c:68 · non-static · windows 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: adapters_get, add_adapter
Library and system calls: free

libs/windows/windows_common_functions.c

The common lib functions (common_lib.h) for Windows

get_pcap

static const npcap_t *get_pcap(lib_common_t *common_lib)

libs/windows/windows_common_functions.c:14 · static · windows build only

The Npcap table, an empty one (no capture) if the lib couldn't start

Called by: init_common_struct, common_lib_terminate, tick, disable_all, toggle_ifname

init_common_struct

lib_common_t *init_common_struct()

libs/windows/windows_common_functions.c:22 · non-static · windows 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, get_pcap, set_interfaces, lib_windows_init
Library and system calls: malloc

common_lib_terminate

int1 common_lib_terminate(lib_common_t *common_lib)

libs/windows/windows_common_functions.c:35 · non-static · windows build only

The capture handles are closed before Npcap is unloaded

Called by: netotter
Calls: if_tab_delete, get_pcap, lib_windows_destroy, close_all_sockets, free_os_data, resolver_close
Library and system calls: free

tick

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

libs/windows/windows_common_functions.c:51 · non-static · windows 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: get_pcap, nw_tick

disable_all

int disable_all(lib_common_t *common_lib)

libs/windows/windows_common_functions.c:59 · non-static · windows 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: get_pcap, close_all_sockets

find_itrf

static interface_t *find_itrf(lib_common_t *common_lib, int if_id)

libs/windows/windows_common_functions.c:73 · static · windows build only

The interface with that id, NULL if none

Called by: toggle_ifname, get_ifname_state
Calls: my_write

toggle_ifname

enum IFN_STATE toggle_ifname(lib_common_t *common_lib, int if_id)

libs/windows/windows_common_functions.c:85 · non-static · windows 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: get_pcap, find_itrf, nw_open_socket, nw_close_socket

get_ifname_state

enum IFN_STATE get_ifname_state(lib_common_t *common_lib, int if_id)

libs/windows/windows_common_functions.c:98 · non-static · windows 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: find_itrf

libs/windows/windows_input.c

Waiting for the interactive mode's input on stdin. Windows has no poll() on a console, so stdin is checked every WAIT_SLICE_MS until the timeout.

console_key_typed

static int console_key_typed(HANDLE in)

libs/windows/windows_input.c:20 · static · windows build only

1 as soon as a key that types a character is pressed, 0 if none yet, -1 when it can't be checked. Unlike a Linux terminal, the console only echoes (and lets the line be edited) while a read() waits, so waiting here for the whole line would hide it until Enter: the read() takes over from the first character. Ticks pause while the line is typed.

Called by: stdin_wait
Library and system calls: GetNumberOfConsoleInputEvents, PeekConsoleInputW, free, malloc

pipe_ready

static int pipe_ready(HANDLE in)

libs/windows/windows_input.c:51 · static · windows build only

Pipes (MSYS2 / mintty terminals, redirected input): 1 when bytes are waiting or the writer closed it, 0 if not yet, -1 when it can't be checked

Called by: stdin_wait
Library and system calls: GetLastError, PeekNamedPipe

stdin_wait

int stdin_wait(lib_common_t *common_lib, int timeout_ms)

libs/windows/windows_input.c:62 · non-static · windows build only

When stdin can't be checked, it reports it as ready: the read() that follows then sees the real state (data, end of input or error)

Called by: run_interactive
Calls: console_key_typed, pipe_ready
Library and system calls: GetFileType, GetStdHandle, Sleep

libs/windows/windows_lib.c

Main file for the windows-specific lib: the interface list, from Npcap's devices named after their Windows adapters

find_adapter

static IP_ADAPTER_ADDRESSES *find_adapter(IP_ADAPTER_ADDRESSES *adapters, const pcap_if_t *dev)

libs/windows/windows_lib.c:23 · static · windows build only

The Windows adapter of an Npcap device (\Device\NPF_{GUID}: the same {GUID} as its AdapterName), NULL if none. Npcap's loopback device has no GUID: it's the loopback pseudo-interface (loopback_0), the one that holds 127.0.0.1 and ::1.

Called by: describe
Library and system calls: _stricmp, strchr, strstr

ascii_dup

static char *ascii_dup(const char *str)

libs/windows/windows_lib.c:41 · static · windows build only

An allocated copy of str, keeping only printable ASCII ('?' for the rest). NULL if str is NULL or on error.

Called by: describe, append_device
Library and system calls: malloc, strlen

fallback_name

static void fallback_name(char name[WIN_IFNAME_SIZE], int pos)

libs/windows/windows_lib.c:55 · static · windows build only

"npf_<pos>" into name, for a device with no Windows adapter

Called by: describe
Calls: my_strlen, my_strncpy

describe

static enum PACKET_SRC describe(IP_ADAPTER_ADDRESSES *adapters, const pcap_if_t *dev, int pos, char name[WIN_IFNAME_SIZE], char **desc)

libs/windows/windows_lib.c:72 · static · windows build only

The device's name, description and type, from its Windows adapter

Called by: append_device
Calls: adapter_short_name, adapter_desc, find_adapter, ascii_dup, fallback_name

append_device

static void append_device(interface_t **if_tab, IP_ADAPTER_ADDRESSES *adapters, const pcap_if_t *dev, int pos)

libs/windows/windows_lib.c:87 · static · windows build only

Appends one Npcap device to if_tab, with its win_if_t

Called by: set_interfaces
Calls: if_tab_append, ascii_dup, describe
Library and system calls: free, malloc

set_interfaces

interface_t **set_interfaces(const npcap_t *pcap)

libs/windows/windows_lib.c:113 · non-static · windows build only

Called by: init_common_struct
Calls: my_putstr, adapters_get, append_device
Library and system calls: calloc, free

lib_windows_init

lib_windows_t *lib_windows_init()

libs/windows/windows_lib.c:143 · non-static · windows build only

Called by: init_common_struct
Calls: npcap_load
Library and system calls: malloc

lib_windows_destroy

void lib_windows_destroy(lib_windows_t *lib_windows)

libs/windows/windows_lib.c:153 · non-static · windows build only

Called by: common_lib_terminate
Calls: npcap_unload
Library and system calls: free

close_all_sockets

void close_all_sockets(const npcap_t *pcap, interface_t **itrfs)

libs/windows/windows_lib.c:161 · non-static · windows build only

Called by: common_lib_terminate, disable_all
Calls: nw_close_socket

free_os_data

void free_os_data(interface_t **itrfs)

libs/windows/windows_lib.c:169 · non-static · windows build only

Frees every interface's win_if_t (after close_all_sockets) (from libs/windows/windows_lib.h)

Called by: common_lib_terminate
Library and system calls: free

same_file

int same_file(int fd_a, int fd_b)

libs/windows/windows_lib.c:184 · non-static · windows build only

Windows' stat() has no inode (st_ino is always 0): a file is its volume serial number and file index

Called by: parse_args
Library and system calls: GetFileInformationByHandle, _get_osfhandle

my_usleep

void my_usleep(uint32_t usec)

libs/windows/windows_lib.c:205 · non-static · windows build only

Sleep() counts in milliseconds: rounded up, so a short wait still waits

Called by: run_cli
Library and system calls: Sleep

local_date

int local_date(uint64_t sec, date_t *out)

libs/windows/windows_lib.c:210 · non-static · windows build only

The local date of sec seconds since the Unix epoch into out. No common_lib: it needs no backend state. 0 on success, 1 if the time can't be converted. (from includes/common_lib.h)

Called by: print_capture_time
Library and system calls: _localtime64_s

term_colors

int term_colors(void)

libs/windows/windows_lib.c:227 · non-static · windows build only

%LOCALAPPDATA% is per user and never roams to other machines

Called by: colors, print_alert
Library and system calls: GetConsoleMode, GetStdHandle, SetConsoleMode

cache_file_path

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

libs/windows/windows_lib.c:240 · non-static · windows build only

The path of NetOtter's cache file name into buf (size bytes): $XDG_CACHE_HOME/netotter (~/.cache/netotter without it) on Linux, %LOCALAPPDATA%\NetOtter on Windows. With create, the missing directories are created first (readable by the user only on Linux). No lib_common_t: it's called before and after the backend runs. 0 on success, -1 if there's no such place or it can't be created. (from includes/common_lib.h)

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

libs/windows/windows_network.c

Windows specific packet access: one Npcap capture handle per enabled interface, read without blocking on each tick, with Npcap's drop count reported

nw_open_error

static void nw_open_error(const npcap_t *pcap, interface_t *itrf, pcap_t *handle, int status)

libs/windows/windows_network.c:25 · static · windows build only

Npcap's error for a handle, or the text of a pcap_activate status

Called by: nw_open_socket
Calls: my_putstr

nw_open_socket

void nw_open_socket(const npcap_t *pcap, interface_t *itrf)

libs/windows/windows_network.c:39 · non-static · windows build only

Called by: toggle_ifname
Calls: my_putstr, nw_open_error

nw_close_socket

void nw_close_socket(const npcap_t *pcap, interface_t *itrf)

libs/windows/windows_network.c:78 · non-static · windows build only

Called by: toggle_ifname, close_all_sockets
Calls: my_putstr

static enum LINK_TYPE nw_link_type(int dlt)

libs/windows/windows_network.c:91 · static · windows build only

pcap link type -> core link type

Called by: nw_recv_one

nw_recv_one

static queue_t *nw_recv_one(const npcap_t *pcap, interface_t *itrf, int *stop)

libs/windows/windows_network.c:103 · static · windows build only

Called by: nw_tick
Calls: my_write, nw_link_type
Library and system calls: malloc, memcpy

nw_drops

static uint32_t nw_drops(const npcap_t *pcap, win_if_t *win)

libs/windows/windows_network.c:144 · static · windows build only

Frames Npcap dropped since the last tick (its buffer was full)

Called by: nw_tick
Library and system calls: memset

nw_tick_report

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

libs/windows/windows_network.c:157 · static · windows build only

Called by: nw_tick
Calls: my_putunbr, my_strlen, my_write

nw_tick

void nw_tick(const npcap_t *pcap, interface_t *itrf, queue_t **q)

libs/windows/windows_network.c:173 · non-static · windows build only

Called by: tick
Calls: nw_recv_one, nw_drops, nw_tick_report

libs/windows/windows_pcap.c

Loads Npcap's wpcap.dll at runtime: without Npcap, NetOtter still starts (no capture, but saves load and display)

resolve

static void (*resolve(HMODULE dll, const char *name, int *missing))

libs/windows/windows_pcap.c:20 · static · windows build only

The function named name, NULL (and *missing set) if wpcap.dll has none. FARPROC goes through void (*)(void), which GCC lets cast to any function type: with C23, FARPROC's () means (void) and a direct cast warns.

Called by: npcap_load
Library and system calls: GetProcAddress

load_wpcap

static HMODULE load_wpcap(void)

libs/windows/windows_pcap.c:35 · static · windows build only

wpcap.dll from System32\Npcap: LOAD_WITH_ALTERED_SEARCH_PATH makes Windows look for its Packet.dll in that same folder. Then the WinPcap-compatible install, in System32 itself.

Called by: npcap_load
Library and system calls: GetSystemDirectoryW, LoadLibraryExW, wcscpy, wcslen

npcap_load

int npcap_load(npcap_t *pcap)

libs/windows/windows_pcap.c:51 · non-static · windows build only

Loads wpcap.dll from the Npcap install folder (or System32 for the WinPcap-compatible mode), never from the exe's folder or the current one. 0 on success, -1 if Npcap isn't there (pcap->dll stays NULL). (from libs/windows/windows_pcap.h)

Called by: lib_windows_init
Calls: resolve, load_wpcap
Library and system calls: FreeLibrary, memset

npcap_unload

void npcap_unload(npcap_t *pcap)

libs/windows/windows_pcap.c:84 · non-static · windows build only

Called by: lib_windows_destroy
Library and system calls: FreeLibrary, memset

libs/windows/windows_resolver.c

The UDP socket NetOtter's own reverse DNS lookups go through (online mode only): the first DNS server Windows uses, and the random source for the query ids

first_nameserver

static int first_nameserver(char *addr, int size)

libs/windows/windows_resolver.c:26 · static · windows build only

The first DNS server of the system configuration (IPv4) into addr (size bytes). 0 on success, -1 if there is none.

Called by: resolver_open
Library and system calls: GetNetworkParams, free, malloc, memcpy, strcmp, strlen

connect_resolver

static SOCKET connect_resolver(const char *addr)

libs/windows/windows_resolver.c:55 · static · windows build only

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

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

resolver_open

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

libs/windows/windows_resolver.c:89 · non-static · windows 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
Library and system calls: WSAStartup

resolver_send

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

libs/windows/windows_resolver.c:107 · non-static · windows 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/windows/windows_resolver.c:121 · non-static · windows build only

A connected UDP socket on Windows reports an ICMP "port unreachable" for an earlier query as WSAECONNRESET on the next recv: skipped, the answers waiting behind it are still read

Called by: reverse_tick
Library and system calls: WSAGetLastError, recv

random_bytes

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

libs/windows/windows_resolver.c:138 · non-static · windows 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: BCryptGenRandom

resolver_close

void resolver_close(lib_common_t *common_lib)

libs/windows/windows_resolver.c:150 · non-static · windows build only

Called by: reverse_toggle_online, common_lib_terminate
Library and system calls: WSACleanup, closesocket

libs/windows/windows_spool.c

The payload spool on Windows: a temporary file in the cache directory, deleted by Windows when its handle is closed (FILE_FLAG_DELETE_ON_CLOSE). Windows has no pread / pwrite: the offsets go through an OVERLAPPED structure.

decimal

static void decimal(uint32_t n, char *buf)

libs/windows/windows_spool.c:25 · static · windows build only

n in decimal into buf (11 bytes at least), '\0'-terminated

Called by: spool_name

spool_name

static int spool_name(const char *dir, int attempt, char *path, int size)

libs/windows/windows_spool.c:41 · static · windows build only

dir + "payloads-<pid>-<attempt>.tmp" into path. 0 on success, -1 if it doesn't fit.

Called by: create_spool
Calls: my_strappend, decimal
Library and system calls: GetCurrentProcessId

create_spool

static HANDLE create_spool(const char *dir)

libs/windows/windows_spool.c:59 · static · windows build only

Called by: spool_open
Calls: spool_name
Library and system calls: CreateFileA, GetLastError

spool_open

spool_t *spool_open(char *dir, int size)

libs/windows/windows_spool.c:78 · non-static · windows 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, create_spool
Library and system calls: free, malloc

set_offset

static void set_offset(OVERLAPPED *ov, uint64_t off)

libs/windows/windows_spool.c:97 · static · windows build only

Called by: spool_write_at, spool_read_at
Library and system calls: memset

spool_write_at

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

libs/windows/windows_spool.c:104 · non-static · windows build only

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

Called by: store_flush
Calls: set_offset
Library and system calls: WriteFile

spool_read_at

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

libs/windows/windows_spool.c:121 · non-static · windows build only

Called by: store_stored_bytes
Calls: set_offset
Library and system calls: ReadFile

spool_close

void spool_close(spool_t *spool)

libs/windows/windows_spool.c:137 · non-static · windows build only

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