1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2010 Lennart Poettering
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <netinet/ether.h>
24 #include <netinet/in.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
30 #include <linux/netlink.h>
31 #include <linux/if_infiniband.h>
32 #include <linux/if_packet.h>
38 union sockaddr_union {
40 struct sockaddr_in in;
41 struct sockaddr_in6 in6;
42 struct sockaddr_un un;
43 #if 0 /// UNNEEDED by elogind, only 'sa', 'in', 'in6' and 'un' are used in all of elogind.
44 struct sockaddr_nl nl;
45 struct sockaddr_storage storage;
46 struct sockaddr_ll ll;
47 struct sockaddr_vm vm;
49 /* Ensure there is enough space to store Infiniband addresses */
50 uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)];
53 #if 0 /// UNNEEDED by elogind
54 typedef struct SocketAddress {
55 union sockaddr_union sockaddr;
57 /* We store the size here explicitly due to the weird
58 * sockaddr_un semantics for abstract sockets */
61 /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */
64 /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
68 typedef enum SocketAddressBindIPv6Only {
69 SOCKET_ADDRESS_DEFAULT,
71 SOCKET_ADDRESS_IPV6_ONLY,
72 _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX,
73 _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1
74 } SocketAddressBindIPv6Only;
76 #define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
78 const char* socket_address_type_to_string(int t) _const_;
79 int socket_address_type_from_string(const char *s) _pure_;
81 int socket_address_parse(SocketAddress *a, const char *s);
82 int socket_address_parse_and_warn(SocketAddress *a, const char *s);
83 int socket_address_parse_netlink(SocketAddress *a, const char *s);
84 int socket_address_print(const SocketAddress *a, char **p);
85 int socket_address_verify(const SocketAddress *a) _pure_;
86 int socket_address_unlink(SocketAddress *a);
88 bool socket_address_can_accept(const SocketAddress *a) _pure_;
90 int socket_address_listen(
91 const SocketAddress *a,
94 SocketAddressBindIPv6Only only,
95 const char *bind_to_device,
99 mode_t directory_mode,
102 int make_socket_fd(int log_level, const char* address, int type, int flags);
104 bool socket_address_is(const SocketAddress *a, const char *s, int type);
105 bool socket_address_is_netlink(const SocketAddress *a, const char *s);
107 bool socket_address_matches_fd(const SocketAddress *a, int fd);
109 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
111 const char* socket_address_get_path(const SocketAddress *a);
113 bool socket_ipv6_is_supported(void);
115 int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
117 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
118 int getpeername_pretty(int fd, bool include_port, char **ret);
119 int getsockname_pretty(int fd, char **ret);
121 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
122 int getnameinfo_pretty(int fd, char **ret);
124 const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
125 SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
126 SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *s);
128 int netlink_family_to_string_alloc(int b, char **s);
129 int netlink_family_from_string(const char *s) _pure_;
131 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
134 int fd_inc_sndbuf(int fd, size_t n);
135 int fd_inc_rcvbuf(int fd, size_t n);
136 #if 0 /// UNNEEDED by elogind
138 int ip_tos_to_string_alloc(int i, char **s);
139 int ip_tos_from_string(const char *s);
141 bool ifname_valid(const char *p);
142 bool address_label_valid(const char *p);
145 int getpeercred(int fd, struct ucred *ucred);
146 int getpeersec(int fd, char **ret);
148 int send_one_fd_sa(int transport_fd,
150 const struct sockaddr *sa, socklen_t len,
152 #define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags)
153 #if 0 /// UNNEEDED by elogind
154 int receive_one_fd(int transport_fd, int flags);
156 ssize_t next_datagram_size_fd(int fd);
158 int flush_accept(int fd);
161 #define CMSG_FOREACH(cmsg, mh) \
162 for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
164 #if 0 /// UNNEEDED by elogind
165 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
169 * Certain hardware address types (e.g Infiniband) do not fit into sll_addr
170 * (8 bytes) and run over the structure. This macro returns the correct size that
171 * must be passed to kernel.
173 #define SOCKADDR_LL_LEN(sa) \
175 const struct sockaddr_ll *_sa = &(sa); \
176 size_t _mac_len = sizeof(_sa->sll_addr); \
177 assert(_sa->sll_family == AF_PACKET); \
178 if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER) \
179 _mac_len = MAX(_mac_len, (size_t) ETH_ALEN); \
180 if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND) \
181 _mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
182 offsetof(struct sockaddr_ll, sll_addr) + _mac_len; \
185 /* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
186 #define SOCKADDR_UN_LEN(sa) \
188 const struct sockaddr_un *_sa = &(sa); \
189 assert(_sa->sun_family == AF_UNIX); \
190 offsetof(struct sockaddr_un, sun_path) + \
191 (_sa->sun_path[0] == 0 ? \
192 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
193 strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
196 #if 0 /// UNNEEDED by elogind
197 int socket_ioctl_fd(void);