]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/socket-util.h
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / socket-util.h
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
c2f1db8f 2#pragma once
42f4e3c4 3
a7334b09
LP
4/***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
12 (at your option) any later version.
13
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
5430f7f2 17 Lesser General Public License for more details.
a7334b09 18
5430f7f2 19 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
db73295a 23#include <netinet/ether.h>
71d35b6b 24#include <netinet/in.h>
11c3a366
TA
25#include <stdbool.h>
26#include <stddef.h>
71d35b6b 27#include <sys/socket.h>
11c3a366 28#include <sys/types.h>
42f4e3c4 29#include <sys/un.h>
7a22745a 30#include <linux/netlink.h>
b1f24b75 31#include <linux/if_infiniband.h>
e88bc795 32#include <linux/if_packet.h>
42f4e3c4
LP
33
34#include "macro.h"
0fc0f14b 35#include "missing.h"
42f4e3c4
LP
36#include "util.h"
37
f6144808
LP
38union sockaddr_union {
39 struct sockaddr sa;
4d49b48c 40 struct sockaddr_in in;
f6144808
LP
41 struct sockaddr_in6 in6;
42 struct sockaddr_un un;
7a22745a 43 struct sockaddr_nl nl;
f6144808 44 struct sockaddr_storage storage;
e88bc795 45 struct sockaddr_ll ll;
0fc0f14b 46 struct sockaddr_vm vm;
b1f24b75
BG
47 /* Ensure there is enough space to store Infiniband addresses */
48 uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)];
f6144808
LP
49};
50
542563ba 51typedef struct SocketAddress {
f6144808 52 union sockaddr_union sockaddr;
42f4e3c4
LP
53
54 /* We store the size here explicitly due to the weird
55 * sockaddr_un semantics for abstract sockets */
56 socklen_t size;
57
58 /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */
59 int type;
7a22745a
LP
60
61 /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
62 int protocol;
542563ba 63} SocketAddress;
42f4e3c4 64
542563ba
LP
65typedef enum SocketAddressBindIPv6Only {
66 SOCKET_ADDRESS_DEFAULT,
67 SOCKET_ADDRESS_BOTH,
c0120d99
LP
68 SOCKET_ADDRESS_IPV6_ONLY,
69 _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX,
70 _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1
542563ba 71} SocketAddressBindIPv6Only;
42f4e3c4 72
542563ba 73#define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
42f4e3c4 74
542563ba 75int socket_address_parse(SocketAddress *a, const char *s);
7693146d 76int socket_address_parse_and_warn(SocketAddress *a, const char *s);
7a22745a 77int socket_address_parse_netlink(SocketAddress *a, const char *s);
542563ba 78int socket_address_print(const SocketAddress *a, char **p);
44a6b1b6 79int socket_address_verify(const SocketAddress *a) _pure_;
bd1fe7c7 80int socket_address_unlink(SocketAddress *a);
b5a0699f 81
44a6b1b6 82bool socket_address_can_accept(const SocketAddress *a) _pure_;
4f2d528d 83
b5a0699f
LP
84int socket_address_listen(
85 const SocketAddress *a,
175a3d25 86 int flags,
b5a0699f
LP
87 int backlog,
88 SocketAddressBindIPv6Only only,
89 const char *bind_to_device,
54255c64 90 bool reuse_port,
4fd5948e 91 bool free_bind,
6b6d2dee 92 bool transparent,
b5a0699f
LP
93 mode_t directory_mode,
94 mode_t socket_mode,
175a3d25 95 const char *label);
7b7afdfc 96int make_socket_fd(int log_level, const char* address, int type, int flags);
42f4e3c4 97
27ca8d7a 98bool socket_address_is(const SocketAddress *a, const char *s, int type);
7a22745a 99bool socket_address_is_netlink(const SocketAddress *a, const char *s);
a16e1123 100
01e10de3
LP
101bool socket_address_matches_fd(const SocketAddress *a, int fd);
102
44a6b1b6 103bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
a16e1123 104
a57f7e2c 105const char* socket_address_get_path(const SocketAddress *a);
6e2ef85b 106
4d49b48c
LP
107bool socket_ipv6_is_supported(void);
108
69dc6922 109int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
3b1c5241
SL
110
111int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
366b7db4 112int getpeername_pretty(int fd, bool include_port, char **ret);
4d49b48c
LP
113int getsockname_pretty(int fd, char **ret);
114
b31f535c
ZJS
115int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
116int getnameinfo_pretty(int fd, char **ret);
117
44a6b1b6
ZJS
118const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
119SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
c0120d99 120
f8b69d1d 121int netlink_family_to_string_alloc(int b, char **s);
4d49b48c 122int netlink_family_from_string(const char *s) _pure_;
f01e5736
LP
123
124bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
2583fbea
LP
125
126int fd_inc_sndbuf(int fd, size_t n);
127int fd_inc_rcvbuf(int fd, size_t n);
128
129int ip_tos_to_string_alloc(int i, char **s);
130int ip_tos_from_string(const char *s);
131
ef76dff2 132bool ifname_valid(const char *p);
26808948 133bool address_label_valid(const char *p);
ef76dff2 134
2583fbea
LP
135int getpeercred(int fd, struct ucred *ucred);
136int getpeersec(int fd, char **ret);
137
726f4c47
ZJS
138int send_one_fd_sa(int transport_fd,
139 int fd,
140 const struct sockaddr *sa, socklen_t len,
141 int flags);
142#define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags)
2583fbea 143int receive_one_fd(int transport_fd, int flags);
8f328d36 144
4edc2c9b
LP
145ssize_t next_datagram_size_fd(int fd);
146
60d9771c
LP
147int flush_accept(int fd);
148
8f328d36
LP
149#define CMSG_FOREACH(cmsg, mh) \
150 for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
fc2fffe7 151
29206d46
LP
152struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
153
b1f24b75
BG
154/*
155 * Certain hardware address types (e.g Infiniband) do not fit into sll_addr
156 * (8 bytes) and run over the structure. This macro returns the correct size that
157 * must be passed to kernel.
158 */
159#define SOCKADDR_LL_LEN(sa) \
160 ({ \
161 const struct sockaddr_ll *_sa = &(sa); \
162 size_t _mac_len = sizeof(_sa->sll_addr); \
163 assert(_sa->sll_family == AF_PACKET); \
164 if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER) \
165 _mac_len = MAX(_mac_len, (size_t) ETH_ALEN); \
166 if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND) \
167 _mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
168 offsetof(struct sockaddr_ll, sll_addr) + _mac_len; \
169 })
170
fc2fffe7
LP
171/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
172#define SOCKADDR_UN_LEN(sa) \
173 ({ \
174 const struct sockaddr_un *_sa = &(sa); \
175 assert(_sa->sun_family == AF_UNIX); \
176 offsetof(struct sockaddr_un, sun_path) + \
177 (_sa->sun_path[0] == 0 ? \
178 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
179 strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
180 })
429b4350
LP
181
182int socket_ioctl_fd(void);