]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/dhcp6-network.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2014 Intel Corporation. All rights reserved.
7 #include <netinet/in.h>
8 #include <netinet/ip6.h>
11 #include <sys/socket.h>
12 #include <sys/types.h>
14 #include <linux/if_packet.h>
16 #include "dhcp6-internal.h"
17 #include "dhcp6-protocol.h"
19 #include "socket-util.h"
21 int dhcp6_network_bind_udp_socket(int index
, struct in6_addr
*local_address
) {
22 union sockaddr_union src
= {
23 .in6
.sin6_family
= AF_INET6
,
24 .in6
.sin6_port
= htobe16(DHCP6_PORT_CLIENT
),
25 .in6
.sin6_scope_id
= index
,
27 _cleanup_close_
int s
= -1;
31 assert(local_address
);
33 src
.in6
.sin6_addr
= *local_address
;
35 s
= socket(AF_INET6
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, IPPROTO_UDP
);
39 r
= setsockopt_int(s
, IPPROTO_IPV6
, IPV6_V6ONLY
, true);
43 r
= setsockopt_int(s
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, false);
47 r
= setsockopt_int(s
, SOL_SOCKET
, SO_REUSEADDR
, true);
51 r
= bind(s
, &src
.sa
, sizeof(src
.in6
));
58 int dhcp6_network_send_udp_socket(int s
, struct in6_addr
*server_address
,
59 const void *packet
, size_t len
) {
60 union sockaddr_union dest
= {
61 .in6
.sin6_family
= AF_INET6
,
62 .in6
.sin6_port
= htobe16(DHCP6_PORT_SERVER
),
66 assert(server_address
);
68 memcpy(&dest
.in6
.sin6_addr
, server_address
, sizeof(dest
.in6
.sin6_addr
));
70 r
= sendto(s
, packet
, len
, 0, &dest
.sa
, sizeof(dest
.in6
));