]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/dhcp6-network.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright (C) 2014 Intel Corporation. All rights reserved.
9 #include <netinet/in.h>
10 #include <netinet/ip6.h>
13 #include <sys/socket.h>
14 #include <sys/types.h>
16 #include <linux/if_packet.h>
18 #include "dhcp6-internal.h"
19 #include "dhcp6-protocol.h"
21 #include "socket-util.h"
23 int dhcp6_network_bind_udp_socket(int index
, struct in6_addr
*local_address
) {
24 union sockaddr_union src
= {
25 .in6
.sin6_family
= AF_INET6
,
26 .in6
.sin6_port
= htobe16(DHCP6_PORT_CLIENT
),
27 .in6
.sin6_scope_id
= index
,
29 _cleanup_close_
int s
= -1;
30 int r
, off
= 0, on
= 1;
33 assert(local_address
);
35 src
.in6
.sin6_addr
= *local_address
;
37 s
= socket(AF_INET6
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, IPPROTO_UDP
);
41 r
= setsockopt(s
, IPPROTO_IPV6
, IPV6_V6ONLY
, &on
, sizeof(on
));
45 r
= setsockopt(s
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &off
, sizeof(off
));
49 r
= setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
));
53 r
= bind(s
, &src
.sa
, sizeof(src
.in6
));
60 int dhcp6_network_send_udp_socket(int s
, struct in6_addr
*server_address
,
61 const void *packet
, size_t len
) {
62 union sockaddr_union dest
= {
63 .in6
.sin6_family
= AF_INET6
,
64 .in6
.sin6_port
= htobe16(DHCP6_PORT_SERVER
),
68 assert(server_address
);
70 memcpy(&dest
.in6
.sin6_addr
, server_address
, sizeof(dest
.in6
.sin6_addr
));
72 r
= sendto(s
, packet
, len
, 0, &dest
.sa
, sizeof(dest
.in6
));