hss/docs/hss_parse_services.md

3 KiB
Raw Permalink Blame History

hss_parse_services / hss_parse_config

Source: hss-ports.h:39 and hss-ports.h:58

Builds the candidate port list from /etc/services and the user's ~/.config/.hssrc config file.

hss_parse_services

static void hss_parse_services(struct hss_port_entry *e, int *n);

Reads /etc/services, the system-wide service database, and adds matching ports to the list via hss_add_entry.

Parsing

FILE *f = fopen("/etc/services", "r");
while (fgets(line, sizeof(line), f)) {
    if (line[0] == '#' || line[0] == '\n') continue;
    end = -1;
    if (sscanf(line, "%63s %d-%d/%15s", name, &start, &end, proto) < 4 &&
        scanf(line, "%63s %d/%15s", name, &start, proto) != 3) continue;
  • Skip comments and blank lines.
  • Accept two formats: name start-end/proto (range) and name start/proto (single port).
  • If the first sscanf matches fewer than 4 fields, try the single-port form. If neither matches, skip the line.

Range handling

if (end < 0) end = start;
if (end - start + 1 > 20) end = start + 19;
for (int p = start; p <= end; p++)
    if (p > 0 && p < 65536 && hss_is_common_port(p))
        hss_add_entry(e, n, p, name);
  • If the entry was a single port, end == start.
  • Ranges longer than 20 ports are capped (start + 19) to avoid adding huge blocks of ephemeral ports.
  • Only ports passing hss_is_common_port() are added — that function (hss-ports.h:20) accepts ports 1–1023 and the curated modern-port list (8080, 8443, 3000, 5000, etc.).

IPv6 skip

if (strstr(proto, "6")) continue;

Entries whose protocol contains "6" (e.g., tcp6) are skipped. The tool only probes IPv4 (AF_INET) because hss_get_eth_ips enumerates IPv4 addresses only.

hss_parse_config

static void hss_parse_config(const char *path, struct hss_port_entry *e, int *n);

Reads a user config file (default: ~/.config/.hssrc) and adds ports.

Path expansion

if (path[0] == '~') {
    if (!getenv("HOME")) return;
    snprintf(expanded, sizeof(expanded), "%s%s", getenv("HOME"), path + 1);
    path = expanded;
}

If the path starts with ~, expand it using $HOME. If HOME is unset, skip silently.

Parsing

while (fgets(line, sizeof(line), f)) {
    if (line[0] == '#' || line[0] == '\n') continue;
    int port = atoi(line);
    if (port > 0 && port < 65536) hss_add_entry(e, n, port, NULL);
}
  • Skip comments and blank lines.
  • Convert each line to an integer with atoi.
  • Valid ports (1–65535) are added with NULL name (displayed as the port number).

The config file is line-based — one port per line:

# extra ports to scan
9090
5432
3306

Call order

In hss.c, the sources are loaded in priority order:

  1. hss_parse_services — system-wide common ports.
  2. Built-in modern-port list (hss_modern_ports) — hardcoded in hss-ports.h:11.
  3. hss_parse_config — user overrides.

Because hss_add_entry deduplicates, the same port appearing in multiple sources is only probed once.