Table of Contents
- Windows backend
- libs/windows/windows_adapters.c
- libs/windows/windows_addresses.c
- libs/windows/windows_common_functions.c
- get_pcap
- init_common_struct
- common_lib_terminate
- tick
- disable_all
- find_itrf
- toggle_ifname
- get_ifname_state
- libs/windows/windows_input.c
- libs/windows/windows_lib.c
- find_adapter
- ascii_dup
- fallback_name
- describe
- append_device
- set_interfaces
- lib_windows_init
- lib_windows_destroy
- close_all_sockets
- free_os_data
- same_file
- my_usleep
- local_date
- term_colors
- cache_file_path
- libs/windows/windows_network.c
- nw_open_error
- nw_open_socket
- nw_close_socket
- nw_link_type
- nw_recv_one
- nw_drops
- nw_tick_report
- nw_tick
- libs/windows/windows_pcap.c
- libs/windows/windows_resolver.c
- first_nameserver
- connect_resolver
- resolver_open
- resolver_send
- resolver_recv
- random_bytes
- resolver_close
- libs/windows/windows_spool.c
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
secseconds 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. (fromincludes/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
nameinto 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. (fromincludes/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
nw_link_type
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
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