unet-cli: strip initial newline in usage message
[project/unetd.git] / utils.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #ifndef __UNETD_UTILS_H
6 #define __UNETD_UTILS_H
7
8 #include <string.h>
9 #include <netinet/in.h>
10 #include <libubox/utils.h>
11
12 struct nl_msg;
13
14 union network_addr {
15 struct {
16 uint8_t network_id[8];
17 uint8_t host_addr[8];
18 };
19 struct in_addr in;
20 struct in6_addr in6;
21 };
22
23 union network_endpoint {
24 struct sockaddr sa;
25 struct sockaddr_in in;
26 struct sockaddr_in6 in6;
27 };
28
29 static inline void *
30 network_endpoint_addr(union network_endpoint *ep, int *addr_len)
31 {
32 if (ep->sa.sa_family == AF_INET6) {
33 if (addr_len)
34 *addr_len = sizeof(ep->in6.sin6_addr);
35 return &ep->in6.sin6_addr;
36 }
37
38 if (addr_len)
39 *addr_len = sizeof(ep->in.sin_addr);
40 return &ep->in.sin_addr;
41 }
42
43 static inline bool
44 network_endpoint_addr_equal(union network_endpoint *ep1, union network_endpoint *ep2)
45 {
46 const void *a1, *a2;
47 int len;
48
49 if (ep1->sa.sa_family != ep2->sa.sa_family)
50 return false;
51
52 a1 = network_endpoint_addr(ep1, &len);
53 a2 = network_endpoint_addr(ep2, &len);
54
55 return !memcmp(a1, a2, len);
56 }
57
58 int network_get_endpoint(union network_endpoint *dest, int af, const char *str,
59 int default_port, int idx);
60 int network_get_subnet(int af, union network_addr *addr, int *mask,
61 const char *str);
62 int network_get_local_addr(void *local, const union network_endpoint *target);
63
64 void *unet_read_file(const char *name, size_t *len);
65
66 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
67
68 #define bitmask_size(len) (4 * DIV_ROUND_UP(len, 32))
69
70 static inline bool bitmask_test(uint32_t *mask, unsigned int i)
71 {
72 return mask[i / 32] & (1 << (i % 32));
73 }
74
75 static inline void bitmask_set(uint32_t *mask, unsigned int i)
76 {
77 mask[i / 32] |= 1 << (i % 32);
78 }
79
80 static inline void bitmask_clear(uint32_t *mask, unsigned int i)
81 {
82 mask[i / 32] &= ~(1 << (i % 32));
83 }
84
85 static inline void bitmask_set_val(uint32_t *mask, unsigned int i, bool val)
86 {
87 if (val)
88 bitmask_set(mask, i);
89 else
90 bitmask_clear(mask, i);
91 }
92
93 static inline uint16_t get_unaligned_be16(const uint8_t *p)
94 {
95 return p[1] | p[0] << 8;
96 }
97
98 static inline uint32_t get_unaligned_be32(const uint8_t *p)
99 {
100 return p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24;
101 }
102
103 static inline uint64_t get_unaligned_be64(const uint8_t *p)
104 {
105 return (uint64_t)get_unaligned_be32(p) << 32 |
106 get_unaligned_be32(p + 4);
107 }
108
109 static inline uint16_t get_unaligned_le16(const uint8_t *p)
110 {
111 return p[0] | p[1] << 8;
112 }
113
114 static inline uint32_t get_unaligned_le32(const uint8_t *p)
115 {
116 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
117 }
118
119 static inline uint64_t get_unaligned_le64(const uint8_t *p)
120 {
121 return (uint64_t)get_unaligned_le32(p + 4) << 32 |
122 get_unaligned_le32(p);
123 }
124
125 int rtnl_init(void);
126 int rtnl_call(struct nl_msg *msg);
127
128 uint64_t unet_gettime(void);
129
130 int sendto_rawudp(int fd, const void *addr, void *ip_hdr, size_t ip_hdrlen,
131 const void *data, size_t len);
132
133 #endif