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