1 /* vi: set sw=4 ts=4: */
2 /*
3  * Copyright (C) 2011 Denys Vlasenko.
4  *
5  * Licensed under GPLv2, see file LICENSE in this source tree.
6  */
7 #ifndef UDHCP_D6_COMMON_H
8 #define UDHCP_D6_COMMON_H 1
9 
10 #include <netinet/ip6.h>
11 
12 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
13 
14 
15 /*** DHCPv6 packet ***/
16 
17 /* DHCPv6 protocol. See RFC 3315 */
18 #define D6_MSG_SOLICIT              1
19 #define D6_MSG_ADVERTISE            2
20 #define D6_MSG_REQUEST              3
21 #define D6_MSG_CONFIRM              4
22 #define D6_MSG_RENEW                5
23 #define D6_MSG_REBIND               6
24 #define D6_MSG_REPLY                7
25 #define D6_MSG_RELEASE              8
26 #define D6_MSG_DECLINE              9
27 #define D6_MSG_RECONFIGURE         10
28 #define D6_MSG_INFORMATION_REQUEST 11
29 #define D6_MSG_RELAY_FORW          12
30 #define D6_MSG_RELAY_REPL          13
31 
32 struct d6_packet {
33 	union {
34 		uint8_t d6_msg_type;
35 		uint32_t d6_xid32;
36 	} d6_u;
37 	uint8_t d6_options[576 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) - 4
38 			+ CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
39 } PACKED;
40 #define d6_msg_type d6_u.d6_msg_type
41 #define d6_xid32    d6_u.d6_xid32
42 
43 struct ip6_udp_d6_packet {
44 	struct ip6_hdr ip6;
45 	struct udphdr udp;
46 	struct d6_packet data;
47 } PACKED;
48 
49 struct udp_d6_packet {
50 	struct udphdr udp;
51 	struct d6_packet data;
52 } PACKED;
53 
54 /*** Options ***/
55 
56 struct d6_option {
57 	uint8_t code_hi;
58 	uint8_t code;
59 	uint8_t len_hi;
60 	uint8_t len;
61 	uint8_t data[1];
62 } PACKED;
63 
64 #define D6_OPT_CLIENTID       1
65 #define D6_OPT_SERVERID       2
66 #define D6_OPT_IA_NA          3
67 #define D6_OPT_IA_TA          4
68 #define D6_OPT_IAADDR         5
69 #define D6_OPT_ORO            6
70 #define D6_OPT_PREFERENCE     7
71 #define D6_OPT_ELAPSED_TIME   8
72 #define D6_OPT_RELAY_MSG      9
73 #define D6_OPT_AUTH          11
74 #define D6_OPT_UNICAST       12
75 #define D6_OPT_STATUS_CODE   13
76 #define D6_OPT_RAPID_COMMIT  14
77 #define D6_OPT_USER_CLASS    15
78 #define D6_OPT_VENDOR_CLASS  16
79 #define D6_OPT_VENDOR_OPTS   17
80 #define D6_OPT_INTERFACE_ID  18
81 #define D6_OPT_RECONF_MSG    19
82 #define D6_OPT_RECONF_ACCEPT 20
83 
84 #define D6_OPT_DNS_SERVERS   23
85 #define D6_OPT_DOMAIN_LIST   24
86 
87 #define D6_OPT_IA_PD         25
88 #define D6_OPT_IAPREFIX      26
89 
90 /* RFC 4704 "The DHCPv6 Client FQDN Option"
91  * uint16	option-code	OPTION_CLIENT_FQDN (39)
92  * uint16	option-len	1 + length of domain name
93  * uint8	flags
94  * char[]	domain-name	partial or fully qualified domain name
95  *
96  * Flags format is |MBZ|N|O|S|
97  * The "S" bit indicates whether the server SHOULD or SHOULD NOT perform
98  * the AAAA RR (FQDN-to-address) DNS updates.  A client sets the bit to
99  * 0 to indicate that the server SHOULD NOT perform the updates and 1 to
100  * indicate that the server SHOULD perform the updates.  The state of
101  * the bit in the reply from the server indicates the action to be taken
102  * by the server; if it is 1, the server has taken responsibility for
103  * AAAA RR updates for the FQDN.
104  * The "O" bit indicates whether the server has overridden the client's
105  * preference for the "S" bit.  A client MUST set this bit to 0.  A
106  * server MUST set this bit to 1 if the "S" bit in its reply to the
107  * client does not match the "S" bit received from the client.
108  * The "N" bit indicates whether the server SHOULD NOT perform any DNS
109  * updates.  A client sets this bit to 0 to request that the server
110  * SHOULD perform updates (the PTR RR and possibly the AAAA RR based on
111  * the "S" bit) or to 1 to request that the server SHOULD NOT perform
112  * any DNS updates.  A server sets the "N" bit to indicate whether the
113  * server SHALL (0) or SHALL NOT (1) perform DNS updates.  If the "N"
114  * bit is 1, the "S" bit MUST be 0.
115  *
116  * If a client knows only part of its name, it MAY send a name that is not
117  * fully qualified, indicating that it knows part of the name but does not
118  * necessarily know the zone in which the name is to be embedded.
119  * To send a fully qualified domain name, the Domain Name field is set
120  * to the DNS-encoded domain name including the terminating zero-length
121  * label.  To send a partial name, the Domain Name field is set to the
122  * DNS-encoded domain name without the terminating zero-length label.
123  * A client MAY also leave the Domain Name field empty if it desires the
124  * server to provide a name.
125  */
126 #define D6_OPT_CLIENT_FQDN   39
127 
128 #define D6_OPT_TZ_POSIX      41
129 #define D6_OPT_TZ_NAME       42
130 
131 #define D6_OPT_BOOT_URL      59
132 #define D6_OPT_BOOT_PARAM    60
133 
134 /*** Other shared functions ***/
135 
136 struct client6_data_t {
137 	struct d6_option *server_id;
138 	struct d6_option *ia_na;
139 	struct d6_option *ia_pd;
140 	char **env_ptr;
141 	unsigned env_idx;
142 	/* link-local IPv6 address */
143 	struct in6_addr ll_ip6;
144 } FIX_ALIASING;
145 
146 #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)]))
147 
148 int FAST_FUNC d6_read_interface(
149 		const char *interface,
150 		int *ifindex,
151 		struct in6_addr *nip6,
152 		uint8_t *mac
153 );
154 
155 int FAST_FUNC d6_listen_socket(int port, const char *inf);
156 
157 int FAST_FUNC d6_recv_kernel_packet(
158 		struct in6_addr *peer_ipv6,
159 		struct d6_packet *packet, int fd
160 );
161 
162 int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
163 		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
164 		struct in6_addr *src_ipv6, int source_port,
165 		struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp
166 );
167 
168 int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
169 		struct d6_packet *d6_pkt, unsigned d6_pkt_size,
170 		struct in6_addr *src_ipv6, int source_port,
171 		struct in6_addr *dst_ipv6, int dest_port
172 );
173 
174 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
175 void FAST_FUNC d6_dump_packet(struct d6_packet *packet);
176 #else
177 # define d6_dump_packet(packet) ((void)0)
178 #endif
179 
180 
181 POP_SAVED_FUNCTION_VISIBILITY
182 
183 #endif
184