summaryrefslogtreecommitdiff
path: root/src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h
blob: 274b14b056e2a56d25be36c1f45c58179ce47a68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

/***
  Copyright © 2014-2015 Intel Corporation. All rights reserved.
***/

#include <net/ethernet.h>
#include <netinet/in.h>

#include "sd-event.h"
#include "sd-dhcp6-client.h"

#include "hashmap.h"
#include "list.h"
#include "log-link.h"
#include "macro.h"
#include "sparse-endian.h"

typedef struct sd_dhcp6_option {
        unsigned n_ref;

        uint32_t enterprise_identifier;
        uint16_t option;
        void *data;
        size_t length;
} sd_dhcp6_option;

extern const struct hash_ops dhcp6_option_hash_ops;

/* Common option header */
typedef struct DHCP6Option {
        be16_t code;
        be16_t len;
        uint8_t data[];
} _packed_ DHCP6Option;

/* Address option */
struct iaaddr {
        struct in6_addr address;
        be32_t lifetime_preferred;
        be32_t lifetime_valid;
} _packed_;

/* Prefix Delegation Prefix option */
struct iapdprefix {
        be32_t lifetime_preferred;
        be32_t lifetime_valid;
        uint8_t prefixlen;
        struct in6_addr address;
} _packed_;

typedef struct DHCP6Address DHCP6Address;

struct DHCP6Address {
        LIST_FIELDS(DHCP6Address, addresses);

        union {
                struct iaaddr iaaddr;
                struct iapdprefix iapdprefix;
        };
};

/* Non-temporary Address option */
struct ia_na {
        be32_t id;
        be32_t lifetime_t1;
        be32_t lifetime_t2;
} _packed_;

/* Prefix Delegation option */
struct ia_pd {
        be32_t id;
        be32_t lifetime_t1;
        be32_t lifetime_t2;
} _packed_;

/* Temporary Address option */
struct ia_ta {
        be32_t id;
} _packed_;

typedef struct DHCP6IA {
        uint16_t type;
        union {
                struct ia_na ia_na;
                struct ia_pd ia_pd;
                struct ia_ta ia_ta;
        };

        LIST_HEAD(DHCP6Address, addresses);
} DHCP6IA;

int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                        size_t optlen, const void *optval);
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd, const DHCP6Address *hint_pd_prefix);
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                       size_t *optlen, uint8_t **optvalue);
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
                                struct in6_addr **addrs, size_t count,
                                size_t *allocated);
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
                                       char ***str_arr);
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);

int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
                                  const void *packet, size_t len);

const char *dhcp6_message_type_to_string(int s) _const_;
int dhcp6_message_type_from_string(const char *s) _pure_;
const char *dhcp6_message_status_to_string(int s) _const_;
int dhcp6_message_status_from_string(const char *s) _pure_;

#define log_dhcp6_client_errno(client, error, fmt, ...)                 \
        ({                                                              \
                int _e = (error);                                       \
                if (DEBUG_LOGGING)                                      \
                        log_interface_full_errno(                       \
                                    sd_dhcp6_client_get_ifname(client), \
                                    LOG_DEBUG, _e, "DHCPv6 client: " fmt, \
                                    ##__VA_ARGS__);                     \
                -ERRNO_VALUE(_e);                                       \
        })
#define log_dhcp6_client(client, fmt, ...)                       \
        log_dhcp6_client_errno(client, 0, fmt, ##__VA_ARGS__)