]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/socket-util.h
Merge pull request #6497 from yuwata/bus-prop
[thirdparty/systemd.git] / src / basic / socket-util.h
1 #pragma once
2
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
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/ether.h>
23 #include <netinet/in.h>
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <sys/socket.h>
27 #include <sys/types.h>
28 #include <sys/un.h>
29 #include <linux/netlink.h>
30 #include <linux/if_infiniband.h>
31 #include <linux/if_packet.h>
32
33 #include "macro.h"
34 #include "missing.h"
35 #include "util.h"
36
37 union sockaddr_union {
38 struct sockaddr sa;
39 struct sockaddr_in in;
40 struct sockaddr_in6 in6;
41 struct sockaddr_un un;
42 struct sockaddr_nl nl;
43 struct sockaddr_storage storage;
44 struct sockaddr_ll ll;
45 struct sockaddr_vm vm;
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)];
48 };
49
50 typedef struct SocketAddress {
51 union sockaddr_union sockaddr;
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;
59
60 /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
61 int protocol;
62 } SocketAddress;
63
64 typedef enum SocketAddressBindIPv6Only {
65 SOCKET_ADDRESS_DEFAULT,
66 SOCKET_ADDRESS_BOTH,
67 SOCKET_ADDRESS_IPV6_ONLY,
68 _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX,
69 _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1
70 } SocketAddressBindIPv6Only;
71
72 #define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
73
74 int socket_address_parse(SocketAddress *a, const char *s);
75 int socket_address_parse_and_warn(SocketAddress *a, const char *s);
76 int socket_address_parse_netlink(SocketAddress *a, const char *s);
77 int socket_address_print(const SocketAddress *a, char **p);
78 int socket_address_verify(const SocketAddress *a) _pure_;
79 int socket_address_unlink(SocketAddress *a);
80
81 bool socket_address_can_accept(const SocketAddress *a) _pure_;
82
83 int socket_address_listen(
84 const SocketAddress *a,
85 int flags,
86 int backlog,
87 SocketAddressBindIPv6Only only,
88 const char *bind_to_device,
89 bool reuse_port,
90 bool free_bind,
91 bool transparent,
92 mode_t directory_mode,
93 mode_t socket_mode,
94 const char *label);
95 int make_socket_fd(int log_level, const char* address, int type, int flags);
96
97 bool socket_address_is(const SocketAddress *a, const char *s, int type);
98 bool socket_address_is_netlink(const SocketAddress *a, const char *s);
99
100 bool socket_address_matches_fd(const SocketAddress *a, int fd);
101
102 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
103
104 const char* socket_address_get_path(const SocketAddress *a);
105
106 bool socket_ipv6_is_supported(void);
107
108 int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
109
110 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
111 int getpeername_pretty(int fd, bool include_port, char **ret);
112 int getsockname_pretty(int fd, char **ret);
113
114 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
115 int getnameinfo_pretty(int fd, char **ret);
116
117 const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
118 SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
119
120 int netlink_family_to_string_alloc(int b, char **s);
121 int netlink_family_from_string(const char *s) _pure_;
122
123 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
124
125 int fd_inc_sndbuf(int fd, size_t n);
126 int fd_inc_rcvbuf(int fd, size_t n);
127
128 int ip_tos_to_string_alloc(int i, char **s);
129 int ip_tos_from_string(const char *s);
130
131 bool ifname_valid(const char *p);
132 bool address_label_valid(const char *p);
133
134 int getpeercred(int fd, struct ucred *ucred);
135 int getpeersec(int fd, char **ret);
136
137 int 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)
142 int receive_one_fd(int transport_fd, int flags);
143
144 ssize_t next_datagram_size_fd(int fd);
145
146 int flush_accept(int fd);
147
148 #define CMSG_FOREACH(cmsg, mh) \
149 for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
150
151 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
152
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
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 })
180
181 int socket_ioctl_fd(void);