2.5 KiB
hss_match_process / hss_match_port_token
Source: hss-proc.h:12 and hss-proc.h:19
Heuristically determines whether a process's command line suggests it owns a given port.
hss_match_port_token
static int hss_match_port_token(const char *args, const char *needle);
Checks whether needle (the port number as a string) appears in
args as a whole token, not as a substring of a larger number.
size_t n = strlen(needle);
for (const char *p = args; (p = strstr(p, needle)); p++)
if ((p == args || p[-1] < '0' || p[-1] > '9') &&
(p[n] < '0' || p[n] > '9')) return 1;
return 0;
The boundary check: the character before and after the match must both
be non-digit (or the match is at the start/end of the string). This
prevents 8000 from matching inside 18000 or 80001.
hss_match_process
static int hss_match_process(int port, const char *args, const char *needle);
Two-tier matching strategy:
Tier 1: Known services
Hard-coded associations between well-known services and their ports:
| Service | Port(s) |
|---|---|
sshd |
22 |
httpd, apache, nginx, lighttpd |
80, 443 |
ftp |
21 |
postgres |
5432 |
redis |
6379 |
mysql, mariadb |
3306 |
If the command line contains the service name and the port matches,
it's a direct hit. No token-boundary check needed — sshd on port 22
is unambiguous.
Tier 2: Interpreters
return (strstr(args, "python") || strstr(args, "node") ||
strstr(args, "java") || strstr(args, "ruby")) &&
hss_match_port_token(args, needle);
For interpreted languages, the port number typically appears in the
command line (e.g., python3 -m http.server 8000, node app.js 3000).
The match requires both:
- An interpreter name in the command line.
- The port number as a whole token (via
hss_match_port_token).
This avoids false positives — a java process whose command line
happens to contain 8000 as part of a heap size (-Xmx8000m) won't
match, because 8000 is adjacent to other digits.
Limitations
- Only matches processes whose command line is visible via
proc_getprocargs(all processes, but the args may be truncated or unavailable for kernel-internal tasks). - Cannot detect a process that listens on a port without mentioning it on the command line (e.g., a config-file-only port binding).
- The known-service table is static; new services require a code change.
This is the "heuristic" tradeoff: fast and dependency-free, but not exhaustive.