aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--README.md20
-rw-r--r--udp514-journal.c98
-rw-r--r--udp514-journal.h8
-rw-r--r--udp514-journal.service4
-rw-r--r--udp514-journal.socket15
6 files changed, 114 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index 6f7cdff..9b9bba4 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie
# this is just a fallback in case you do not use git but downloaded
# a release tarball...
-VERSION := 0.1.0
+VERSION := 0.2.1
all: udp514-journal README.html
@@ -32,6 +32,7 @@ install: install-bin install-doc
install-bin: udp514-journal
$(INSTALL) -D -m0755 udp514-journal $(DESTDIR)/usr/bin/udp514-journal
$(INSTALL) -D -m0644 udp514-journal.service $(DESTDIR)/usr/lib/systemd/system/udp514-journal.service
+ $(INSTALL) -D -m0644 udp514-journal.socket $(DESTDIR)/usr/lib/systemd/system/udp514-journal.socket
install-doc: README.html
$(INSTALL) -D -m0644 README.md $(DESTDIR)/usr/share/doc/udp514-journal/README.md
diff --git a/README.md b/README.md
index 1fd4fae..92725fe 100644
--- a/README.md
+++ b/README.md
@@ -24,15 +24,22 @@ followed by:
This will place an executable at `/usr/bin/udp514-journal`,
documentation can be found in `/usr/share/doc/udp514-journal/`.
-Additionally a systemd unit file is installed to
-`/usr/lib/systemd/system/udp514-journal.service`.
+Additionally systemd unit files `udp514-journal.service` and
+`udp514-journal.socket` are installed to
+`/usr/lib/systemd/system/`.
Usage
-----
-Just run `udp514-journal` or start a systemd unit with
-`systemctl start udp514-journal`. Make sure UDP port 514 is not blocked
-in your firewall.
+Just run `udp514-journal` or start a systemd unit with:
+
+ systemctl start udp514-journal.socket
+
+Make sure UDP port 514 is not blocked in your firewall.
+
+To enable it permanently to make it start on system boot run:
+
+ systemctl enable --now udp514-journal.socket
Use `journalctl` to view the logs:
@@ -70,3 +77,6 @@ URL:
Mirror:
[eworm.de](https://git.eworm.de/cgit.cgi/udp514-journal/)
[GitLab.com](https://gitlab.com/eworm-de/udp514-journal#udp514-journal)
+
+---
+[⬆️ Go back to top](#top)
diff --git a/udp514-journal.c b/udp514-journal.c
index 2ab70e1..402785c 100644
--- a/udp514-journal.c
+++ b/udp514-journal.c
@@ -1,5 +1,5 @@
/*
- * (C) 2018-2021 by Christian Hesse <mail@eworm.de>
+ * (C) 2018-2025 by Christian Hesse <mail@eworm.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,24 +19,46 @@
#include "udp514-journal.h"
int main(int argc, char **argv) {
- int sock;
- struct sockaddr_in cliAddr, servAddr;
- const int opt_val = 1;
+ int activation, sock;
unsigned int count = 0;
- /* open socket */
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("could not open socket");
- return EXIT_FAILURE;
- }
+ /* socket address for listening */
+ struct sockaddr_storage ss_listen = {};
+ struct sockaddr *addr_listen = (struct sockaddr *) &ss_listen;
+ struct sockaddr_in *addr_listen_in = (struct sockaddr_in *) &ss_listen;
+ struct sockaddr_in6 *addr_listen_in6 = (struct sockaddr_in6 *) &ss_listen;
+
+ activation = sd_listen_fds(0);
- /* bind local socket port */
- servAddr.sin_family = AF_INET;
- servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servAddr.sin_port = htons(LOCAL_SERVER_PORT);
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));
- if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
- perror("could not bind on port " LOCAL_SERVER_PORT_STR);
+ if (activation > 1) {
+ perror("too many file descriptors received");
+ return EXIT_FAILURE;
+ } else if (activation == 1) {
+ /* use the socket passed from systemd */
+ sock = SD_LISTEN_FDS_START + 0;
+ } else if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) > 0) {
+ /* bind local socket port - IPv6 */
+ addr_listen_in6->sin6_family = AF_INET6;
+ addr_listen_in6->sin6_addr = in6addr_any;
+ addr_listen_in6->sin6_scope_id = 0;
+ addr_listen_in6->sin6_port = htons(LOCAL_SERVER_PORT);
+ if (bind(sock, addr_listen, sizeof(struct sockaddr_in6)) < 0) {
+ perror("could not bind on port " LOCAL_SERVER_PORT_STR);
+ close(sock);
+ return EXIT_FAILURE;
+ }
+ } else if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) > 0) {
+ /* bind local socket port - fallback IPv4 */
+ addr_listen_in->sin_family = AF_INET;
+ addr_listen_in->sin_addr.s_addr = htonl(INADDR_ANY);
+ addr_listen_in->sin_port = htons(LOCAL_SERVER_PORT);
+ if (bind(sock, addr_listen, sizeof(struct sockaddr_in)) < 0) {
+ perror("could not bind on port " LOCAL_SERVER_PORT_STR);
+ close(sock);
+ return EXIT_FAILURE;
+ }
+ } else {
+ perror("could not open socket");
return EXIT_FAILURE;
}
@@ -45,21 +67,28 @@ int main(int argc, char **argv) {
/* server loop */
while (1) {
- char buffer[BUFFER_SIZE];
+ char addr_buf[INET6_ADDRSTRLEN], msg_buf[BUFFER_SIZE];
+ const char * address;
socklen_t len;
char * match;
CODE * pri;
uint8_t priority = LOG_INFO;
- memset(buffer, 0, BUFFER_SIZE);
- len = sizeof(cliAddr);
- if (recvfrom(sock, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &cliAddr, &len) < 0) {
+ /* socket address for client */
+ struct sockaddr_storage ss_client = {};
+ struct sockaddr *addr_client = (struct sockaddr *) &ss_client;
+ struct sockaddr_in *addr_client_in = (struct sockaddr_in *) &ss_client;
+ struct sockaddr_in6 *addr_client_in6 = (struct sockaddr_in6 *) &ss_client;
+
+ memset(msg_buf, 0, BUFFER_SIZE);
+ len = sizeof(struct sockaddr_storage);
+ if (recvfrom(sock, msg_buf, BUFFER_SIZE, 0, addr_client, &len) < 0) {
perror("could not receive data");
continue;
}
/* parse priority */
- if ((match = strndup(buffer, BUFFER_SIZE)) != NULL) {
+ if ((match = strndup(msg_buf, BUFFER_SIZE)) != NULL) {
char * space = strchr(match, ' ');
if (space != NULL)
*space = 0;
@@ -68,9 +97,32 @@ int main(int argc, char **argv) {
priority = pri->c_val;
}
+ /* get client's ip address */
+ switch (addr_client->sa_family) {
+ case AF_INET6:
+ const struct in6_addr *in6_addr = &addr_client_in6->sin6_addr;
+ address = inet_ntop(AF_INET6, in6_addr, addr_buf, INET6_ADDRSTRLEN);
+ /* strip prefix (::ffff:) from mapped ipv4 addresses */
+ if (address && IN6_IS_ADDR_V4MAPPED(in6_addr)) {
+ address += 7;
+ }
+ break;
+ case AF_INET:
+ const struct in_addr *in_addr = &addr_client_in->sin_addr;
+ address = inet_ntop(AF_INET, in_addr, addr_buf, INET6_ADDRSTRLEN);
+ break;
+ default:
+ fputs("unhadled address family", stderr);
+ continue;
+ }
+ if (address == NULL) {
+ perror("could not get clients ip address");
+ continue;
+ }
+
/* send to systemd-journald */
- sd_journal_send("MESSAGE=%s", buffer,
- "SYSLOG_IDENTIFIER=%s", inet_ntoa(cliAddr.sin_addr),
+ sd_journal_send("MESSAGE=%s", msg_buf,
+ "SYSLOG_IDENTIFIER=%s", address,
"PRIORITY=%i", priority,
NULL);
diff --git a/udp514-journal.h b/udp514-journal.h
index 0054a8b..72e4c6d 100644
--- a/udp514-journal.h
+++ b/udp514-journal.h
@@ -1,5 +1,5 @@
/*
- * (C) 2018-2021 by Christian Hesse <mail@eworm.de>
+ * (C) 2018-2025 by Christian Hesse <mail@eworm.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +21,6 @@
#define _POSIX_C_SOURCE 200809L
-#define SYSLOG_NAMES
-
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -35,6 +33,10 @@
#include <errno.h>
#include <time.h>
+#define SYSLOG_NAMES
+#define __USE_MISC
+#include <sys/syslog.h>
+
#include <systemd/sd-journal.h>
#include <systemd/sd-daemon.h>
diff --git a/udp514-journal.service b/udp514-journal.service
index 4ae2ca0..9bcc367 100644
--- a/udp514-journal.service
+++ b/udp514-journal.service
@@ -1,4 +1,4 @@
-# (C) 2018-2021 by Christian Hesse <mail@eworm.de>
+# (C) 2018-2025 by Christian Hesse <mail@eworm.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -8,6 +8,7 @@
[Unit]
Description=Forward syslog from network (udp/514) to journal
Requires=systemd-journald.socket
+Requires=udp514-journal.socket
After=network.target
[Service]
@@ -15,7 +16,6 @@ Type=notify
Restart=always
ExecStart=/usr/bin/udp514-journal
DynamicUser=on
-AmbientCapabilities=CAP_NET_BIND_SERVICE
ProtectSystem=full
ProtectHome=on
PrivateDevices=on
diff --git a/udp514-journal.socket b/udp514-journal.socket
new file mode 100644
index 0000000..4158536
--- /dev/null
+++ b/udp514-journal.socket
@@ -0,0 +1,15 @@
+# (C) 2018-2025 by Christian Hesse <mail@eworm.de>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Forward syslog from network (udp/514) to journal
+
+[Socket]
+ListenDatagram=514
+
+[Install]
+WantedBy=sockets.target