1 | /* |
2 | * Copyright (c) 2012-2017 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License |
8 | * Version 2.0 (the 'License'). You may not use this file except in |
9 | * compliance with the License. The rights granted to you under the License |
10 | * may not be used to create, or enable the creation or redistribution of, |
11 | * unlawful or unlicensed copies of an Apple operating system, or to |
12 | * circumvent, violate, or enable the circumvention or violation of, any |
13 | * terms of an Apple operating system software license agreement. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
17 | * |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and |
24 | * limitations under the License. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | |
29 | #ifndef _NETINET_MPTCP_H_ |
30 | #define _NETINET_MPTCP_H_ |
31 | |
32 | #ifdef BSD_KERNEL_PRIVATE |
33 | |
34 | #include <machine/endian.h> |
35 | |
36 | #include <libkern/crypto/sha1.h> |
37 | |
38 | #if BYTE_ORDER == BIG_ENDIAN |
39 | #define mptcp_hton64(x) (x) |
40 | #define mptcp_ntoh64(x) (x) |
41 | #else /* LITTLE_ENDIAN */ |
42 | #define mptcp_hton64(x) __DARWIN_OSSwapInt64(x) |
43 | #define mptcp_ntoh64(x) __DARWIN_OSSwapInt64(x) |
44 | #endif |
45 | #include <netinet/mptcp_var.h> |
46 | |
47 | /* Preferred MPTCP version to use when version discovery info is incomplete */ |
48 | extern int mptcp_preferred_version; |
49 | |
50 | /* |
51 | * MPTCP Option Subtype Field values |
52 | */ |
53 | #define MPO_CAPABLE 0x0 |
54 | #define MPO_JOIN 0x1 |
55 | #define MPO_DSS 0x2 |
56 | #define MPO_ADD_ADDR 0x3 |
57 | #define MPO_REMOVE_ADDR 0x4 |
58 | #define MPO_PRIO 0x5 |
59 | #define MPO_FAIL 0x6 |
60 | #define MPO_FASTCLOSE 0x7 |
61 | |
62 | /* MPTCP Protocol version */ |
63 | #define MPTCP_VERSION_0 0x0 |
64 | #define MPTCP_VERSION_1 0x1 |
65 | |
66 | /* |
67 | * MPTCP MP_CAPABLE TCP Option definitions |
68 | * |
69 | * Used to establish an MPTCP connection and first subflow. |
70 | */ |
71 | struct mptcp_mpcapable_opt_common { |
72 | uint8_t mmco_kind; |
73 | uint8_t mmco_len; |
74 | #if BYTE_ORDER == LITTLE_ENDIAN |
75 | uint8_t mmco_version:4, |
76 | mmco_subtype:4; |
77 | #else /* BIG_ENDIAN */ |
78 | uint8_t mmco_subtype:4, |
79 | mmco_version:4; |
80 | #endif |
81 | #define MPCAP_PROPOSAL_SBIT 0x01 /* SHA1 (v0) or SHA256 (v1) Algorithm */ |
82 | #define MPCAP_GBIT 0x02 /* must be 0 */ |
83 | #define MPCAP_FBIT 0x04 /* must be 0 */ |
84 | #define MPCAP_EBIT 0x08 /* must be 0 */ |
85 | #define MPCAP_DBIT 0x10 /* must be 0 */ |
86 | #define MPCAP_UNICAST_IPBIT 0x20 /* Should MPTCP only use ADD_ADDR IPs for new subflows */ |
87 | #define MPCAP_BBIT 0x40 /* Extensibility bit, must be 0 */ |
88 | #define MPCAP_CHECKSUM_CBIT 0x80 /* DSS Checksum bit */ |
89 | uint8_t mmco_flags; |
90 | } __attribute__((__packed__)); |
91 | |
92 | struct mptcp_mpcapable_opt_rsp { |
93 | struct mptcp_mpcapable_opt_common mmc_common; |
94 | mptcp_key_t mmc_localkey; |
95 | } __attribute__((__packed__)); |
96 | |
97 | struct mptcp_mpcapable_opt_rsp1 { |
98 | struct mptcp_mpcapable_opt_common mmc_common; |
99 | mptcp_key_t mmc_localkey; |
100 | mptcp_key_t mmc_remotekey; |
101 | } __attribute__((__packed__)); |
102 | |
103 | struct mptcp_mpcapable_opt_rsp2 { |
104 | struct mptcp_mpcapable_opt_rsp1 mmc_rsp1; |
105 | uint16_t data_len; |
106 | uint16_t csum; |
107 | } __attribute__((__packed__)); |
108 | |
109 | /* |
110 | * MPTCP MP_JOIN TCP Option definitions |
111 | * |
112 | * Used to add subflows to an existing MP_CAPABLE connection. |
113 | */ |
114 | |
115 | /* MP_JOIN Option for SYN */ |
116 | struct mptcp_mpjoin_opt_req { |
117 | uint8_t mmjo_kind; |
118 | uint8_t mmjo_len; |
119 | #define MPTCP_BACKUP 0x1 |
120 | uint8_t mmjo_subtype_bkp; |
121 | uint8_t mmjo_addr_id; |
122 | uint32_t mmjo_peer_token; |
123 | uint32_t mmjo_rand; |
124 | } __attribute__((__packed__)); |
125 | |
126 | /* MP_JOIN Option for SYN/ACK */ |
127 | struct mptcp_mpjoin_opt_rsp { |
128 | uint8_t mmjo_kind; |
129 | uint8_t mmjo_len; |
130 | #define MPTCP_BACKUP 0x1 |
131 | uint8_t mmjo_subtype_bkp; |
132 | uint8_t mmjo_addr_id; |
133 | uint64_t mmjo_mac; /* Truncated message auth code */ |
134 | uint32_t mmjo_rand; |
135 | } __attribute__((__packed__)); |
136 | |
137 | /* MP_Join Option for ACK */ |
138 | struct mptcp_mpjoin_opt_rsp2 { |
139 | uint8_t mmjo_kind; |
140 | uint8_t mmjo_len; |
141 | #if BYTE_ORDER == LITTLE_ENDIAN |
142 | uint8_t mmjo_reserved1:4, |
143 | mmjo_subtype:4; |
144 | #else /* BIG_ENDIAN */ |
145 | uint8_t mmjo_subtype:4, |
146 | mmjo_reserved1:4; |
147 | #endif |
148 | uint8_t mmjo_reserved2; |
149 | uint8_t mmjo_mac[HMAC_TRUNCATED_ACK]; /* This is 160 bits HMAC per RFC */ |
150 | } __attribute__((__packed__)); |
151 | |
152 | /* Remove Address Option */ |
153 | struct mptcp_remaddr_opt { |
154 | uint8_t mr_kind; |
155 | uint8_t mr_len; |
156 | #if BYTE_ORDER == LITTLE_ENDIAN |
157 | uint8_t mr_rest:4, |
158 | mr_subtype:4; |
159 | #else /* BIG_ENDIAN */ |
160 | uint8_t mr_subtype:4, |
161 | mr_rest:4; |
162 | #endif |
163 | uint8_t mr_addr_id; |
164 | } __attribute__((__packed__)); |
165 | |
166 | /* |
167 | * MPTCP Data Sequence Signal (DSS) TCP Options |
168 | * |
169 | * Used to map subflow sequence space to MPTCP data sequence space. |
170 | * Used to send Data ACKs |
171 | */ |
172 | |
173 | /* |
174 | * DSS Option variants coded as flags in the DSS option flags field |
175 | */ |
176 | #define MDSS_A 0x01 /* Data ACK present if set */ |
177 | #define MDSS_a 0x02 /* 64-bit Data ACK present if set */ |
178 | #define MDSS_M 0x04 /* Data Sequence Number present if set */ |
179 | #define MDSS_m 0x08 /* 64-bit Data Sequence Number present if set */ |
180 | #define MDSS_F 0x10 /* Data FIN present */ |
181 | |
182 | /* DSS fields common to all DSS option variants */ |
183 | struct mptcp_dss_copt { |
184 | uint8_t mdss_kind; |
185 | uint8_t mdss_len; |
186 | #if BYTE_ORDER == LITTLE_ENDIAN |
187 | uint8_t mdss_reserved1:4, |
188 | mdss_subtype:4; |
189 | #else /* BIG_ENDIAN */ |
190 | uint8_t mdss_subtype:4, |
191 | mdss_reserved1:4; |
192 | #endif |
193 | uint8_t mdss_flags; |
194 | }__attribute__((__packed__)); |
195 | |
196 | /* 32-bit DSS option */ |
197 | struct mptcp_dsn_opt { |
198 | struct mptcp_dss_copt mdss_copt; |
199 | uint32_t mdss_dsn; /* Data Sequence Number */ |
200 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
201 | uint16_t mdss_data_len; /* Data Length */ |
202 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
203 | }__attribute__((__packed__)); |
204 | |
205 | /* 64-bit DSS option */ |
206 | struct mptcp_dsn64_opt { |
207 | struct mptcp_dss_copt mdss_copt; |
208 | uint64_t mdss_dsn; /* Data Sequence Number */ |
209 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
210 | uint16_t mdss_data_len; /* Data Length */ |
211 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
212 | }__attribute__((__packed__)); |
213 | |
214 | /* 32-bit DSS Data ACK option */ |
215 | struct mptcp_data_ack_opt { |
216 | struct mptcp_dss_copt mdss_copt; |
217 | uint32_t mdss_ack; |
218 | }__attribute__((__packed__)); |
219 | |
220 | /* 64-bit DSS Data ACK option */ |
221 | struct mptcp_data_ack64_opt { |
222 | struct mptcp_dss_copt mdss_copt; |
223 | uint64_t mdss_ack; |
224 | }__attribute__((__packed__)); |
225 | |
226 | /* 32-bit DSS+Data ACK option */ |
227 | struct mptcp_dss_ack_opt { |
228 | struct mptcp_dss_copt mdss_copt; |
229 | uint32_t mdss_ack; /* Data ACK */ |
230 | uint32_t mdss_dsn; /* Data Sequence Number */ |
231 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
232 | uint16_t mdss_data_len; /* Data Length */ |
233 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
234 | }__attribute__((__packed__)); |
235 | |
236 | /* 64-bit DSS+Data ACK option */ |
237 | struct mptcp_dss64_ack64_opt { |
238 | struct mptcp_dss_copt mdss_copt; |
239 | uint64_t mdss_ack; /* Data ACK */ |
240 | uint64_t mdss_dsn; /* Data Sequence Number */ |
241 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
242 | uint16_t mdss_data_len; /* Data Length */ |
243 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
244 | }__attribute__((__packed__)); |
245 | |
246 | /* DSS+Data ACK mixed option variants */ |
247 | struct mptcp_dss32_ack64_opt { |
248 | struct mptcp_dss_copt mdss_copt; |
249 | uint64_t mdss_ack; /* Data ACK */ |
250 | uint32_t mdss_dsn; /* Data Sequence Number */ |
251 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
252 | uint16_t mdss_data_len; /* Data Length */ |
253 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
254 | }__attribute__((__packed__)); |
255 | |
256 | struct mptcp_dss64_ack32_opt { |
257 | struct mptcp_dss_copt mdss_copt; |
258 | uint32_t mdss_ack; /* Data ACK */ |
259 | uint64_t mdss_dsn; /* Data Sequence Number */ |
260 | uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */ |
261 | uint16_t mdss_data_len; /* Data Length */ |
262 | /* uint16_t mdss_xsum; */ /* Data checksum - optional */ |
263 | }__attribute__((__packed__)); |
264 | |
265 | |
266 | /* |
267 | * MPTCP Fast Close Option |
268 | * |
269 | * MPTCP connection is aborted if the FastClose option is received. |
270 | * In future, we may send this option if a MPTCP socket level abort |
271 | * API is supported. |
272 | */ |
273 | struct mptcp_fastclose_opt { |
274 | uint8_t mfast_kind; |
275 | uint8_t mfast_len; |
276 | #if BYTE_ORDER == LITTLE_ENDIAN |
277 | uint8_t mfast_reserved:4, |
278 | mfast_subtype:4; |
279 | #else /* BIG_ENDIAN */ |
280 | uint8_t mfast_subtype:4, |
281 | mfast_reserved:4; |
282 | #endif |
283 | uint8_t mfast_reserved1; |
284 | uint64_t mfast_key; /* Option receiver's key */ |
285 | }__attribute__((__packed__)); |
286 | |
287 | /* |
288 | * MPTCP MP_FAIL Option |
289 | * |
290 | * When DSS checksum is ON, and checksum fails, remote peer may send |
291 | * this option to indicate the failure. Likewise, we may send this |
292 | * option. |
293 | */ |
294 | struct mptcp_mpfail_opt { |
295 | uint8_t mfail_kind; |
296 | uint8_t mfail_len; |
297 | #if BYTE_ORDER == LITTLE_ENDIAN |
298 | uint8_t mfail_reserved:4, |
299 | mfail_subtype:4; |
300 | #else /* BIG_ENDIAN */ |
301 | uint8_t mfail_subtype:4, |
302 | mfail_reserved:4; |
303 | #endif |
304 | uint8_t mfail_reserved1:8; |
305 | uint64_t mfail_dsn; |
306 | }__attribute__((__packed__)); |
307 | |
308 | struct mptcp_add_addr_opt { |
309 | uint8_t maddr_kind; |
310 | uint8_t maddr_len; |
311 | #if BYTE_ORDER == LITTLE_ENDIAN |
312 | uint8_t maddr_flags:4, |
313 | maddr_subtype:4; |
314 | #else /* BIG_ENDIAN */ |
315 | uint8_t maddr_subtype:4, |
316 | maddr_flags:4; |
317 | #endif |
318 | uint8_t maddr_addrid; |
319 | union { |
320 | struct { |
321 | struct in_addr maddr_addrv4; |
322 | uint32_t maddr_pad[3]; |
323 | }; |
324 | |
325 | struct { |
326 | struct in6_addr maddr_addrv6; |
327 | }; |
328 | } maddr_u; |
329 | }__attribute__((__packed__)); |
330 | |
331 | struct mptcp_add_addr_hmac_msg_v4 { |
332 | uint8_t maddr_addrid; |
333 | struct in_addr maddr_addr; |
334 | uint16_t maddr_port; |
335 | }__attribute__((__packed__)); |
336 | |
337 | struct mptcp_add_addr_hmac_msg_v6 { |
338 | uint8_t maddr_addrid; |
339 | struct in6_addr maddr_addr; |
340 | uint16_t maddr_port; |
341 | }__attribute__((__packed__)); |
342 | |
343 | |
344 | #define MPTCP_V0_ADD_ADDR_IPV4 4 |
345 | #define MPTCP_V0_ADD_ADDR_IPV6 6 |
346 | #define MPTCP_V1_ADD_ADDR_ECHO 0x1 |
347 | |
348 | #define MPTCP_V0_ADD_ADDR_OPT_LEN_V4 8 |
349 | #define MPTCP_V0_ADD_ADDR_OPT_LEN_V6 20 |
350 | #define MPTCP_V1_ADD_ADDR_OPT_LEN_V4 16 |
351 | #define MPTCP_V1_ADD_ADDR_OPT_LEN_V6 28 |
352 | #define MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V4 8 |
353 | #define MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V6 20 |
354 | /* |
355 | * MPTCP MP_PRIO Option |
356 | * |
357 | * When a subflow becomes unusable (due to bad radio coverage) or |
358 | * it is the costlier path or it is not the preferred path, the receiver may |
359 | * use this option to let the sender know of its path preference. |
360 | */ |
361 | |
362 | /* Option to change priority of some other subflow(s) using addr_id */ |
363 | struct mptcp_mpprio_addr_opt { |
364 | uint8_t mpprio_kind; |
365 | uint8_t mpprio_len; |
366 | #define MPTCP_MPPRIO_BKP 0x1 |
367 | #if BYTE_ORDER == LITTLE_ENDIAN |
368 | uint8_t mpprio_flags:4, |
369 | mpprio_subtype:4; |
370 | #else /* BIG_ENDIAN */ |
371 | uint8_t mpprio_subtype:4, |
372 | mpprio_flags:4; |
373 | #endif |
374 | uint8_t mpprio_addrid; |
375 | }__attribute__((__packed__)); |
376 | |
377 | #endif /* BSD_KERNEL_PRIVATE */ |
378 | |
379 | #endif /* _NETINET_MPTCP_H_ */ |
380 | |