And use them where they can be applicable.
--- /dev/null
+#!/bin/sh -eu
+
+$1 -dM -include netinet/in.h - </dev/null | \
+ awk '/^#define[ \t]+IPPROTO_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
+ sed -e 's/IPPROTO_//'
smack-util.c
smack-util.h
socket-label.c
+ socket-protocol-list.c
+ socket-protocol-list.h
socket-util.c
socket-util.h
sparse-endian.h
command : [generate_errno_list, cpp],
capture : true)
+generate_socket_protocol_list = find_program('generate-socket-protocol-list.sh')
+socket_protocol_list_txt = custom_target(
+ 'socket-protocol-list.txt',
+ output : 'socket-protocol-list.txt',
+ command : [generate_socket_protocol_list, cpp],
+ capture : true)
+
generated_gperf_headers = []
foreach item : [['af', af_list_txt, 'af', ''],
['arphrd', arphrd_list_txt, 'arphrd', 'ARPHRD_'],
['cap', cap_list_txt, 'capability', ''],
- ['errno', errno_list_txt, 'errno', '']]
+ ['errno', errno_list_txt, 'errno', ''],
+ ['socket-protocol', socket_protocol_list_txt, 'socket_protocol', 'IPPROTO_']]
fname = '@0@-from-name.gperf'.format(item[0])
gperf_file = custom_target(
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+#include <string.h>
+
+#include "socket-protocol-list.h"
+#include "macro.h"
+
+static const struct socket_protocol_name* lookup_socket_protocol(register const char *str, register GPERF_LEN_TYPE len);
+
+#include "socket-protocol-from-name.h"
+#include "socket-protocol-to-name.h"
+
+const char *socket_protocol_to_name(int id) {
+
+ if (id < 0)
+ return NULL;
+
+ if (id >= (int) ELEMENTSOF(socket_protocol_names))
+ return NULL;
+
+ return socket_protocol_names[id];
+}
+
+int socket_protocol_from_name(const char *name) {
+ const struct socket_protocol_name *sc;
+
+ assert(name);
+
+ sc = lookup_socket_protocol(name, strlen(name));
+ if (!sc)
+ return 0;
+
+ return sc->id;
+}
+
+int socket_protocol_max(void) {
+ return ELEMENTSOF(socket_protocol_names);
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+const char *socket_protocol_to_name(int id);
+int socket_protocol_from_name(const char *name);
+
+int socket_protocol_max(void);
--- /dev/null
+BEGIN{
+ print "static const char* const socket_protocol_names[] = { "
+}
+!/HOPOPTS/ {
+ printf " [IPPROTO_%s] = \"%s\",\n", $1, tolower($1)
+}
+END{
+ print "};"
+}
#include "parse-util.h"
#include "path-util.h"
#include "socket.h"
+#include "socket-protocol-list.h"
#include "socket-util.h"
#include "string-util.h"
#include "unit.h"
return 1;
} else if (streq(name, "SocketProtocol")) {
+ const char *p;
int32_t i;
r = sd_bus_message_read(message, "i", &i);
if (r < 0)
return r;
- if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP))
+ p = socket_protocol_to_name(i);
+ if (!p)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i);
+ if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported socket protocol: %s", p);
+
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
s->socket_protocol = i;
- unit_write_settingf(u, flags, name, "%s=%s", name, i == IPPROTO_UDPLITE ? "udplite" : "sctp");
+ unit_write_settingf(u, flags, name, "%s=%s", name, p);
}
return 1;
if (!p)
return log_oom();
- p->type = socket_type_from_string(t);
+ p->type = socket_port_type_from_string(t);
if (p->type < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown Socket type: %s", t);
#include "securebits.h"
#include "securebits-util.h"
#include "signal-util.h"
+#include "socket-protocol-list.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
void *data,
void *userdata) {
Socket *s;
+ int r;
assert(filename);
assert(lvalue);
s = SOCKET(data);
- if (streq(rvalue, "udplite"))
- s->socket_protocol = IPPROTO_UDPLITE;
- else if (streq(rvalue, "sctp"))
- s->socket_protocol = IPPROTO_SCTP;
- else {
+ r = socket_protocol_from_name(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid socket protocol, ignoring: %s", rvalue);
+ return 0;
+ } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue);
return 0;
}
+ s->socket_protocol = r;
+
return 0;
}
#include "signal-util.h"
#include "smack-util.h"
#include "socket.h"
+#include "socket-protocol-list.h"
#include "special.h"
#include "string-table.h"
#include "string-util.h"
SocketType socket_port_type_from_string(const char *s) {
assert(s);
- if (STR_IN_SET(t, "Stream", "Datagram", "SequentialPacket", "Netlink"))
- return = SOCKET_SOCKET;
- else if (streq(t, "Special"))
- return = SOCKET_SPECIAL;
- else if (streq(t, "MessageQueue"))
- return = SOCKET_MQUEUE;
- else if (streq(t, "FIFO"))
- return = SOCKET_FIFO;
- else if (streq(t, "USBFunction"))
- return = SOCKET_USB_FUNCTION;
+ if (STR_IN_SET(s, "Stream", "Datagram", "SequentialPacket", "Netlink"))
+ return SOCKET_SOCKET;
+ else if (streq(s, "Special"))
+ return SOCKET_SPECIAL;
+ else if (streq(s, "MessageQueue"))
+ return SOCKET_MQUEUE;
+ else if (streq(s, "FIFO"))
+ return SOCKET_FIFO;
+ else if (streq(s, "USBFunction"))
+ return SOCKET_USB_FUNCTION;
else
return _SOCKET_TYPE_INVALID;
}
#include "rlimit-util.h"
#include "securebits-util.h"
#include "signal-util.h"
+#include "socket-protocol-list.h"
#include "string-util.h"
#include "syslog-util.h"
#include "terminal-util.h"
DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string)
DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string)
DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder)
+DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name)
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority)
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice)
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi)
return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
- if (streq(field, "SocketProtocol")) {
+ if (streq(field, "SocketProtocol"))
- if (streq(eq, "udplite"))
- r = sd_bus_message_append(m, "(sv)", field, "i", IPPROTO_UDPLITE);
- else if (streq(eq, "sctp"))
- r = sd_bus_message_append(m, "(sv)", field, "i", IPPROTO_SCTP);
- else {
- log_error("Unsupported Socket protocol: %s", eq);
- return -EINVAL;
- }
- if (r < 0)
- return bus_log_create_error(r);
-
- return 1;
- }
+ return bus_append_socket_protocol_from_name(m, field, eq);
if (STR_IN_SET(field,
"ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",