Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,16 @@ add_library(lp_platform STATIC
src/platform/win32/clock_win32.c
src/platform/win32/config_win32.c
src/platform/win32/discovery_win32.c
src/platform/win32/device_store_win32.c
src/platform/win32/isp_win32.c
src/platform/win32/log_win32.c
src/platform/win32/net_win32.c
src/platform/win32/notification_win32.c
src/platform/win32/shortcut_win32.c
src/platform/win32/update_win32.c
)
target_link_libraries(lp_platform PUBLIC lp_core PRIVATE lp_warnings)
target_link_libraries(lp_platform PUBLIC iphlpapi ole32 runtimeobject winhttp ws2_32)
target_link_libraries(lp_platform PUBLIC iphlpapi ole32 runtimeobject winhttp ws2_32 xmllite shlwapi)
# Windows 10/11 API surface (GetIfTable2, GetBestRoute2).
target_compile_definitions(lp_platform PUBLIC _WIN32_WINNT=0x0A00 WIN32_LEAN_AND_MEAN NOMINMAX)

Expand Down
18 changes: 18 additions & 0 deletions include/linkpulse/device_store.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef LINKPULSE_DEVICE_STORE_H
#define LINKPULSE_DEVICE_STORE_H

#include "linkpulse/discovery.h"

/* Opens the per-user MAC-keyed XML device store. The returned handle is opaque. */
int lp_win32_device_store_open(void **store);

/* Applies persisted label, trust, type, and icon metadata to an observation. */
void lp_win32_device_store_apply(void *store, lp_neighbor_t *neighbor);

/* Records observed metadata and persists the store atomically. */
void lp_win32_device_store_observe(void *store, const lp_neighbor_t *neighbor);

/* Releases the store and any XML resources owned by it. */
void lp_win32_device_store_close(void *store);

#endif /* LINKPULSE_DEVICE_STORE_H */
6 changes: 6 additions & 0 deletions include/linkpulse/discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>

#include "linkpulse/isp.h"
#include "linkpulse/status.h"

#define LP_MAC_STR_MAX 18
Expand Down Expand Up @@ -37,10 +38,14 @@ typedef struct {
char ip[LP_IP_STR_MAX];
char mac[LP_MAC_STR_MAX];
char hostname[LP_HOSTNAME_MAX];
char label[LP_HOSTNAME_MAX];
char vendor[LP_VENDOR_MAX];
char icon[LP_VENDOR_MAX];
lp_connection_type_t connection_type;
lp_device_type_t device_type;
uint8_t device_confidence;
bool trusted;
bool has_device_type_override;
bool active;
} lp_neighbor_t;

Expand All @@ -66,6 +71,7 @@ typedef struct {
char local_hostname[LP_HOSTNAME_MAX];
char local_ip[LP_IP_STR_MAX];
lp_connection_type_t local_connection_type;
lp_isp_info_t isp_info;
} lp_local_network_list_t;

typedef lp_status_t (*lp_net_neighbor_snapshot_fn)(lp_neighbor_list_t *out);
Expand Down
35 changes: 35 additions & 0 deletions include/linkpulse/isp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef LINKPULSE_ISP_H
#define LINKPULSE_ISP_H

#include "linkpulse/status.h"

#define LP_ISP_IP_MAX 46
#define LP_ISP_NAME_MAX 128
#define LP_ISP_ASN_MAX 16
#define LP_ISP_HOSTNAME_MAX 256
#define LP_ISP_PLACE_MAX 128
#define LP_ISP_COUNTRY_MAX 8
#define LP_ISP_POSTAL_MAX 16
#define LP_ISP_TIMEZONE_MAX 64
#define LP_ISP_LOC_MAX 32

/* Every field the lookup service can report for the internet-facing connection. */
typedef struct {
char public_ip[LP_ISP_IP_MAX];
char isp[LP_ISP_NAME_MAX]; /* organization name, without the leading ASxxxx */
char asn[LP_ISP_ASN_MAX]; /* e.g. "AS3209" */
char hostname[LP_ISP_HOSTNAME_MAX];
char city[LP_ISP_PLACE_MAX];
char region[LP_ISP_PLACE_MAX];
char country[LP_ISP_COUNTRY_MAX];
char postal[LP_ISP_POSTAL_MAX];
char timezone[LP_ISP_TIMEZONE_MAX];
char loc[LP_ISP_LOC_MAX]; /* "latitude,longitude" */
} lp_isp_info_t;

/* Looks up all available public IP/ISP/location fields via an external HTTPS
lookup service. Populates as many fields as the response provides; missing
fields are left as empty strings. */
lp_status_t lp_isp_lookup(lp_isp_info_t *out);

#endif /* LINKPULSE_ISP_H */
2 changes: 1 addition & 1 deletion src/cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static int list_interfaces(void)

const size_t interface_count = list.count;
lp_iface_list_free(&list);
LP_DEBUG("listed %zu network interfaces", interface_count);
LP_DEBUG("listed %llu network interfaces", (unsigned long long)interface_count);
return 0;
}

Expand Down
16 changes: 13 additions & 3 deletions src/core/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,31 @@ static void format_timestamp(char *out, size_t out_cap)
}
snprintf(out, out_cap, "0000-00-00 00:00:00.000");

time_t now_seconds;
long milliseconds = 0;
#if defined(__MINGW32__)
/* MinGW-w64's bundled <time.h> does not reliably declare C11's
timespec_get/TIME_UTC (confirmed on this project's mingw-cross CI
toolchain), so this path falls back to whole-second resolution. */
now_seconds = time(NULL);
#else
struct timespec now;
if (timespec_get(&now, TIME_UTC) != TIME_UTC) {
return;
}
now_seconds = now.tv_sec;
milliseconds = now.tv_nsec / 1000000L;
#endif

struct tm local_now;
#if defined(_WIN32)
if (localtime_s(&local_now, &now.tv_sec) != 0) {
if (localtime_s(&local_now, &now_seconds) != 0) {
#else
if (localtime_r(&now.tv_sec, &local_now) == NULL) {
if (localtime_r(&now_seconds, &local_now) == NULL) {
#endif
return;
}

const long milliseconds = now.tv_nsec / 1000000L;
snprintf(out, out_cap, "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
local_now.tm_year + 1900, local_now.tm_mon + 1, local_now.tm_mday,
local_now.tm_hour, local_now.tm_min, local_now.tm_sec, milliseconds);
Expand Down
Loading
Loading