diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | README.md | 51 | ||||
| -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, 141 insertions, 38 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 @@ -1,38 +1,53 @@  udp514-journal  ============== +[](https://github.com/eworm-de/udp514-journal/stargazers) +[](https://github.com/eworm-de/udp514-journal/network) +[](https://github.com/eworm-de/udp514-journal/watchers) +  forward syslog from network (udp/514) to systemd-journald +*Use at your own risk*, pay attention to +[license and warranty](#license-and-warranty), and +[disclaimer on external links](#disclaimer-on-external-links)! +  Requirements  ------------  To compile and run `udp514-journal` you need: -* [systemd](https://www.github.com/systemd/systemd) -* [markdown](https://daringfireball.net/projects/markdown/) (HTML documentation) +* [systemd ↗️](https://www.github.com/systemd/systemd) +* [markdown ↗️](https://daringfireball.net/projects/markdown/) (HTML documentation)  Build and install  -----------------  Building and installing is very easy. Just run: -> make +    make  followed by: -> make install +    make install  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: @@ -62,6 +77,21 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  [GNU General Public License](COPYING.md) for more details. +Disclaimer on external links +---------------------------- + +Our website contains links to the websites of third parties ("external +links"). As the content of these websites is not under our control, we +cannot assume any liability for such external content. In all cases, the +provider of information of the linked websites is liable for the content +and accuracy of the information provided. At the point in time when the +links were placed, no infringements of the law were recognisable to us. +As soon as an infringement of the law becomes known to us, we will +immediately remove the link in question. + +> 💡️ **Hint**: All external links are marked with an arrow pointing +> diagonally in an up-right (or north-east) direction (↗️). +  ### Upstream  URL: @@ -70,3 +100,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  |