/src/coturn/src/client/ns_turn_msg_addr.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SPDX-License-Identifier: BSD-3-Clause |
3 | | * |
4 | | * https://opensource.org/license/bsd-3-clause |
5 | | * |
6 | | * Copyright (C) 2011, 2012, 2013 Citrix Systems |
7 | | * |
8 | | * All rights reserved. |
9 | | * |
10 | | * Redistribution and use in source and binary forms, with or without |
11 | | * modification, are permitted provided that the following conditions |
12 | | * are met: |
13 | | * 1. Redistributions of source code must retain the above copyright |
14 | | * notice, this list of conditions and the following disclaimer. |
15 | | * 2. Redistributions in binary form must reproduce the above copyright |
16 | | * notice, this list of conditions and the following disclaimer in the |
17 | | * documentation and/or other materials provided with the distribution. |
18 | | * 3. Neither the name of the project nor the names of its contributors |
19 | | * may be used to endorse or promote products derived from this software |
20 | | * without specific prior written permission. |
21 | | * |
22 | | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
23 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
26 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | | * SUCH DAMAGE. |
33 | | */ |
34 | | |
35 | | #include "ns_turn_msg_addr.h" |
36 | | #include "ns_turn_defs.h" // for nswap16, nswap32 |
37 | | |
38 | | #include <string.h> // for memcpy |
39 | | |
40 | | ////////////////////////////////////////////////////////////////////////////// |
41 | | |
42 | 0 | int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { |
43 | |
|
44 | 0 | if (!cfield || !clen || !ca || !tsx_id) { |
45 | 0 | return -1; |
46 | 0 | } |
47 | | |
48 | 0 | if (ca->ss.sa_family == AF_INET || ca->ss.sa_family == 0) { |
49 | | |
50 | | /* IPv4 address */ |
51 | |
|
52 | 0 | *clen = 8; |
53 | |
|
54 | 0 | cfield[0] = 0; |
55 | 0 | cfield[1] = 1; // IPv4 family |
56 | |
|
57 | 0 | if (xor_ed) { |
58 | | |
59 | | /* Port */ |
60 | 0 | ((uint16_t *)cfield)[1] = (ca->s4.sin_port) ^ nswap16(mc >> 16); |
61 | | |
62 | | /* Address */ |
63 | 0 | ((uint32_t *)cfield)[1] = (ca->s4.sin_addr.s_addr) ^ nswap32(mc); |
64 | |
|
65 | 0 | } else { |
66 | | |
67 | | /* Port */ |
68 | 0 | ((uint16_t *)cfield)[1] = ca->s4.sin_port; |
69 | | |
70 | | /* Address */ |
71 | 0 | ((uint32_t *)cfield)[1] = ca->s4.sin_addr.s_addr; |
72 | 0 | } |
73 | |
|
74 | 0 | } else if (ca->ss.sa_family == AF_INET6) { |
75 | | |
76 | | /* IPv6 address */ |
77 | |
|
78 | 0 | *clen = 20; |
79 | |
|
80 | 0 | cfield[0] = 0; |
81 | 0 | cfield[1] = 2; // IPv6 family |
82 | |
|
83 | 0 | if (xor_ed) { |
84 | |
|
85 | 0 | unsigned int i; |
86 | 0 | uint8_t *dst = ((uint8_t *)cfield) + 4; |
87 | 0 | const uint8_t *src = (const uint8_t *)&(ca->s6.sin6_addr); |
88 | 0 | uint32_t magic = nswap32(mc); |
89 | | |
90 | | /* Port */ |
91 | 0 | ((uint16_t *)cfield)[1] = ca->s6.sin6_port ^ nswap16(mc >> 16); |
92 | | |
93 | | /* Address */ |
94 | |
|
95 | 0 | for (i = 0; i < 4; ++i) { |
96 | 0 | dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]); |
97 | 0 | } |
98 | 0 | for (i = 0; i < 12; ++i) { |
99 | 0 | dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]); |
100 | 0 | } |
101 | |
|
102 | 0 | } else { |
103 | | |
104 | | /* Port */ |
105 | 0 | ((uint16_t *)cfield)[1] = ca->s6.sin6_port; |
106 | | |
107 | | /* Address */ |
108 | 0 | memcpy(((uint8_t *)cfield) + 4, &ca->s6.sin6_addr, 16); |
109 | 0 | } |
110 | |
|
111 | 0 | } else { |
112 | 0 | return -1; |
113 | 0 | } |
114 | | |
115 | 0 | return 0; |
116 | 0 | } |
117 | | |
118 | 0 | int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id) { |
119 | |
|
120 | 0 | if (!cfield || !len || !ca || !tsx_id || (len < 8)) { |
121 | 0 | return -1; |
122 | 0 | } |
123 | | |
124 | 0 | if (cfield[0] != 0) { |
125 | 0 | return -1; |
126 | 0 | } |
127 | | |
128 | 0 | int sa_family; |
129 | |
|
130 | 0 | if (cfield[1] == 1) { |
131 | 0 | sa_family = AF_INET; |
132 | 0 | } else if (cfield[1] == 2) { |
133 | 0 | sa_family = AF_INET6; |
134 | 0 | } else { |
135 | 0 | return -1; |
136 | 0 | } |
137 | | |
138 | 0 | ca->ss.sa_family = sa_family; |
139 | |
|
140 | 0 | if (sa_family == AF_INET) { |
141 | |
|
142 | 0 | if (len != 8) { |
143 | 0 | return -1; |
144 | 0 | } |
145 | | |
146 | | /* IPv4 address */ |
147 | | |
148 | | /* Port */ |
149 | 0 | ca->s4.sin_port = ((const uint16_t *)cfield)[1]; |
150 | | |
151 | | /* Address */ |
152 | 0 | ca->s4.sin_addr.s_addr = ((const uint32_t *)cfield)[1]; |
153 | |
|
154 | 0 | if (xor_ed) { |
155 | 0 | ca->s4.sin_port ^= nswap16(mc >> 16); |
156 | 0 | ca->s4.sin_addr.s_addr ^= nswap32(mc); |
157 | 0 | } |
158 | |
|
159 | 0 | } else if (sa_family == AF_INET6) { |
160 | | |
161 | | /* IPv6 address */ |
162 | |
|
163 | 0 | if (len != 20) { |
164 | 0 | return -1; |
165 | 0 | } |
166 | | |
167 | | /* Port */ |
168 | 0 | ca->s6.sin6_port = ((const uint16_t *)cfield)[1]; |
169 | | |
170 | | /* Address */ |
171 | 0 | memcpy(&ca->s6.sin6_addr, ((const uint8_t *)cfield) + 4, 16); |
172 | |
|
173 | 0 | if (xor_ed) { |
174 | |
|
175 | 0 | unsigned int i; |
176 | 0 | uint8_t *dst; |
177 | 0 | const uint8_t *src; |
178 | 0 | uint32_t magic = nswap32(mc); |
179 | | |
180 | | /* Port */ |
181 | 0 | ca->s6.sin6_port ^= nswap16(mc >> 16); |
182 | | |
183 | | /* Address */ |
184 | 0 | src = ((const uint8_t *)cfield) + 4; |
185 | 0 | dst = (uint8_t *)&ca->s6.sin6_addr; |
186 | 0 | for (i = 0; i < 4; ++i) { |
187 | 0 | dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]); |
188 | 0 | } |
189 | 0 | for (i = 0; i < 12; ++i) { |
190 | 0 | dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]); |
191 | 0 | } |
192 | 0 | } |
193 | |
|
194 | 0 | } else { |
195 | 0 | return -1; |
196 | 0 | } |
197 | | |
198 | 0 | return 0; |
199 | 0 | } |
200 | | |
201 | | ////////////////////////////////////////////////////////////////////////////// |