1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
6 #include <sys/socket.h>
13 int network_get_endpoint(union network_endpoint
*dest
, const char *str
,
14 int default_port
, int idx
)
16 struct addrinfo hints
= {
17 .ai_flags
= AI_ADDRCONFIG
,
18 .ai_family
= AF_UNSPEC
,
20 char *buf
= strdup(str
);
21 char *host
= buf
, *port
;
22 struct addrinfo
*ai
, *ai_cur
;
26 memset(dest
, 0, sizeof(*dest
));
30 port
= strchr(host
, ']');
37 else if (*port
== ':')
41 hints
.ai_family
= AF_INET6
;
42 hints
.ai_flags
|= AI_NUMERICHOST
;
46 port
= strchr(host
, ':');
51 if (getaddrinfo(host
, port
, &hints
, &ai
) || !ai
)
56 for (n_res
= 0; ai_cur
; ai_cur
= ai_cur
->ai_next
, n_res
++)
64 if (ai_cur
->ai_addrlen
> sizeof(*dest
))
67 memcpy(dest
, ai_cur
->ai_addr
, ai_cur
->ai_addrlen
);
69 dest
->in
.sin_port
= htons(default_port
);
80 int network_get_subnet(int af
, union network_addr
*addr
, int *mask
, const char *str
)
82 char *buf
= strdup(str
);
91 sep
= strchr(buf
, '/');
97 val
= strtoul(sep
, &end
, 0);
98 if ((end
&& *end
) || val
> *mask
)
104 if (inet_pton(af
, buf
, addr
) == 1)
112 int network_get_local_addr(void *local
, const union network_endpoint
*target
)
114 union network_endpoint ep
= {};
119 memset(local
, 0, sizeof(union network_addr
));
120 if (target
->sa
.sa_family
== AF_INET6
)
121 len
= sizeof(ep
.in6
);
125 fd
= socket(target
->sa
.sa_family
, SOCK_DGRAM
, IPPROTO_UDP
);
129 if (connect(fd
, (const struct sockaddr
*)target
, len
))
133 if (getsockname(fd
, &ep
.sa
, &len
))
136 if (ep
.sa
.sa_family
== AF_INET6
)
137 memcpy(local
, &ep
.in6
.sin6_addr
, sizeof(ep
.in6
.sin6_addr
));
139 memcpy(local
, &ep
.in
.sin_addr
, sizeof(ep
.in
.sin_addr
));
147 void *unet_read_file(const char *name
, size_t *len
)
153 f
= fopen(name
, "r");
157 if (fstat(fileno(f
), &st
) < 0)
160 if (*len
&& st
.st_size
> *len
)
163 data
= malloc(st
.st_size
);
167 if (fread(data
, 1, st
.st_size
, f
) != st
.st_size
) {