#include #include #include #include #include #include #include #include #include #define MAC_PATH "/sys/class/net/eth0/address" //~ #define MAC_PATH "/sys/class/net/wlp0s20f3/address" #define PROC_TCP "/proc/net/tcp" #define PROGNAME "heartbeat-cli" static volatile int keep_running = 1; void handle_sigint(int sig) { (void)sig; keep_running = 0; } // Check if there is an established TCP connection on given port (state == 1) int check_port_connected(int port) { FILE *fp = fopen(PROC_TCP, "r"); if (!fp) return 0; char line[512]; int connected = 0; // Skip header if (!fgets(line, sizeof(line), fp)) { fclose(fp); return 0; } while (fgets(line, sizeof(line), fp)) { unsigned int local_addr, rem_addr; unsigned int local_port, rem_port, state; if (sscanf(line, "%*d: %x:%x %x:%x %x", &local_addr, &local_port, &rem_addr, &rem_port, &state) == 5) { if (ntohs((unsigned short)rem_port) == ntohs(port) && state == 1) { connected = 1; break; } } } fclose(fp); return connected; } // Get eth0 MAC address void get_mac_address(char *mac_str, size_t len) { FILE *fp = fopen(MAC_PATH, "r"); if (!fp) { snprintf(mac_str, len, "00:00:00:00:00:00"); return; } if (fgets(mac_str, len, fp)) { mac_str[strcspn(mac_str, "\n")] = 0; // remove newline } else { snprintf(mac_str, len, "00:00:00:00:00:00"); } fclose(fp); } int connect_server(const char *ip, int port) { int sock; struct sockaddr_in addr; time_t now = time(NULL); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { //perror("socket"); printf("%ld %s ERROR: socket\n",(long int)now, PROGNAME); return -1; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (inet_pton(AF_INET, ip, &addr.sin_addr) <= 0) { //perror("inet_pton"); now = time(NULL); printf("%ld %s ERROR: inet_pton\n",(long int)now, PROGNAME); close(sock); return -1; } if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { //perror("connect"); now = time(NULL); printf("%ld %s ERROR: inet_pton\n",(long int)now, PROGNAME); close(sock); return -1; } now = time(NULL); //printf("Connected to %s:%d\n", ip, port); printf("%ld %s Connected to %s:%d\n",(long int)now, PROGNAME, ip, port); return sock; } int main(int argc, char *argv[]) { char *server_ip = NULL; int server_port = 0; int interval = 0; int opt; while ((opt = getopt(argc, argv, "s:p:t:")) != -1) { switch (opt) { case 's': server_ip = optarg; break; case 'p': server_port = atoi(optarg); break; case 't': interval = atoi(optarg); break; default: fprintf(stderr, "Usage: %s -s -p -t \n", argv[0]); exit(EXIT_FAILURE); } } if (!server_ip || !server_port || !interval) { fprintf(stderr, "Missing arguments.\n"); fprintf(stderr, "Usage: %s -s -p -t \n", argv[0]); exit(EXIT_FAILURE); } signal(SIGINT, handle_sigint); time_t now = time(NULL); printf("%ld %s Heartbeat to %s:%d every %d seconds\n",(long int)now, PROGNAME,server_ip, server_port, interval); int sock = -1; while (keep_running) { if (sock < 0) { sock = connect_server(server_ip, server_port); if (sock < 0) { now = time(NULL); printf("%ld %s Retrying connection in 5 seconds...\n",(long int)now, PROGNAME); sleep(5); continue; } } time_t now = time(NULL); char mac[32]; get_mac_address(mac, sizeof(mac)); int status = check_port_connected(2404); if(0==status) { status = check_port_connected(12404); } if(0==status) { status = check_port_connected(22404); } char msg[256]; snprintf(msg, sizeof(msg), "{\"mac\": \"%s\",\"status\": %d,\"epoch\": %ld}\n", mac, status, (long int)now); char msg_log[256]; snprintf(msg_log, sizeof(msg_log), "mac: %s status: %d epoch: %ld", mac, status, (long int)now); ssize_t sent = send(sock, msg, strlen(msg), 0); if (sent < 0) { printf("%ld %s Not Sent: %s sendError: %ld\n", (long int)now, PROGNAME, msg_log, (long int)sent); close(sock); sock = -1; sleep(5); continue; } printf("%ld %s Sent: %s\n", (long int)now, PROGNAME, msg_log); sleep(interval); } now = time(NULL); if (sock >= 0) close(sock); printf("%ld %s Heartbeat stopped.\n", (long int)now, PROGNAME); return 0; }