diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README.md | 20 | ||||
-rw-r--r-- | udp514-journal.c | 98 | ||||
-rw-r--r-- | udp514-journal.h | 8 | ||||
-rw-r--r-- | udp514-journal.service | 4 | ||||
-rw-r--r-- | udp514-journal.socket | 15 |
6 files changed, 114 insertions, 34 deletions
@@ -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 @@ -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 |