1
0

Sockaddr.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "rust/cjdns_sys/Rffi.h"
  16. #include "benc/String.h"
  17. #include "memory/Allocator.h"
  18. #include "util/platform/Sockaddr.h"
  19. #include "util/CString.h"
  20. #include "util/Bits.h"
  21. #include "util/Hex.h"
  22. #include "util/Hash.h"
  23. #include "util/Base10.h"
  24. #include <sodium/crypto_hash_sha256.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <stddef.h>
  28. #include <stdint.h>
  29. #include <netinet/in.h>
  30. struct Sockaddr_pvt
  31. {
  32. struct Sockaddr pub;
  33. struct sockaddr_storage ss;
  34. };
  35. void Sockaddr_assertions(void);
  36. void Sockaddr_assertions() {
  37. Assert_compileTime(sizeof(struct Sockaddr) == 8);
  38. Assert_compileTime(sizeof(struct sockaddr_storage) == 128);
  39. Assert_compileTime(sizeof(struct Sockaddr_pvt) == 128+8);
  40. Assert_compileTime(sizeof(struct Sockaddr_storage) == 128+8);
  41. }
  42. struct Sockaddr_in_pvt
  43. {
  44. struct Sockaddr pub;
  45. struct sockaddr_in si;
  46. };
  47. struct Sockaddr_in6_pvt
  48. {
  49. struct Sockaddr pub;
  50. struct sockaddr_in6 si;
  51. };
  52. const struct Sockaddr* const Sockaddr_LOOPBACK_be =
  53. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  54. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  55. .si = {
  56. .sin_family = AF_INET,
  57. .sin_addr = { .s_addr = 0x7f000001 }
  58. }
  59. });
  60. const struct Sockaddr* const Sockaddr_LOOPBACK_le =
  61. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  62. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  63. .si = {
  64. .sin_family = AF_INET,
  65. .sin_addr = { .s_addr = 0x0100007f }
  66. }
  67. });
  68. const struct Sockaddr* const Sockaddr_LOOPBACK6 =
  69. (const struct Sockaddr*) &((const struct Sockaddr_in6_pvt) {
  70. .pub = { .addrLen = sizeof(struct Sockaddr_in6_pvt) },
  71. .si = {
  72. .sin6_family = AF_INET6,
  73. .sin6_addr = { .s6_addr = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
  74. }
  75. });
  76. int Sockaddr_getPrefix(struct Sockaddr* addr)
  77. {
  78. if (addr->flags & Sockaddr_flags_PREFIX) {
  79. return addr->prefix;
  80. }
  81. int af = Sockaddr_getFamily(addr);
  82. if (af == Sockaddr_AF_INET) {
  83. return 32;
  84. } else if (af == Sockaddr_AF_INET6) {
  85. return 128;
  86. } else {
  87. return -1;
  88. }
  89. }
  90. int Sockaddr_parse(const char* input, struct Sockaddr_storage* out)
  91. {
  92. struct Sockaddr_storage unusedOut;
  93. if (!out) {
  94. out = &unusedOut;
  95. }
  96. uint8_t buff[64] = {0};
  97. if (CString_strlen(input) > 63) {
  98. return -1;
  99. }
  100. CString_safeStrncpy(buff, input, 63);
  101. int64_t port = 0;
  102. char* lastColon = CString_strrchr(buff, ':');
  103. char* firstColon = CString_strchr(buff, ':');
  104. char* bracket = CString_strchr(buff, ']');
  105. if (!lastColon) {
  106. // ipv4, no port
  107. } else if (lastColon != firstColon && (!bracket || lastColon < bracket)) {
  108. // ipv6, no port
  109. } else {
  110. if (bracket && lastColon != &bracket[1]) { return -1; }
  111. if (Base10_fromString(&lastColon[1], &port)) { return -1; }
  112. if (port > 65535) { return -1; }
  113. *lastColon = '\0';
  114. }
  115. if (bracket) {
  116. *bracket = '\0';
  117. if (buff[0] != '[') { return -1; }
  118. } else if (buff[0] == '[') { return -1; }
  119. int64_t prefix = -1;
  120. char* slash = CString_strchr(buff, '/');
  121. if (slash) {
  122. *slash = '\0';
  123. if (!slash[1]) { return -1; }
  124. if (Base10_fromString(&slash[1], &prefix)) { return -1; }
  125. }
  126. Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
  127. if (lastColon != firstColon) {
  128. // ipv6
  129. struct sockaddr_in6* in6 = (struct sockaddr_in6*) Sockaddr_asNative(&out->addr);
  130. if (Rffi_inet_pton(1, (char*) ((buff[0] == '[') ? &buff[1] : buff), (uint8_t*) &in6->sin6_addr)) {
  131. return -1;
  132. }
  133. out->addr.addrLen = sizeof(struct sockaddr_in6) + Sockaddr_OVERHEAD;
  134. in6->sin6_port = Endian_hostToBigEndian16(port);
  135. in6->sin6_family = AF_INET6;
  136. } else {
  137. struct sockaddr_in* in = ((struct sockaddr_in*) Sockaddr_asNative(&out->addr));
  138. if (Rffi_inet_pton(0, (char*) buff, (uint8_t*) &in->sin_addr)) {
  139. return -1;
  140. }
  141. out->addr.addrLen = sizeof(struct sockaddr_in) + Sockaddr_OVERHEAD;
  142. in->sin_port = Endian_hostToBigEndian16(port);
  143. in->sin_family = AF_INET;
  144. }
  145. if (prefix != -1) {
  146. if (prefix < 0 || prefix > 128) { return -1; }
  147. if (Sockaddr_getFamily(&out->addr) == Sockaddr_AF_INET && prefix > 32) { return -1; }
  148. out->addr.prefix = prefix;
  149. out->addr.flags |= Sockaddr_flags_PREFIX;
  150. }
  151. return 0;
  152. }
  153. struct Sockaddr* Sockaddr_clone(const struct Sockaddr* addr, struct Allocator* alloc)
  154. {
  155. struct Sockaddr* out = Allocator_malloc(alloc, addr->addrLen);
  156. Bits_memcpy(out, addr, addr->addrLen);
  157. return out;
  158. }
  159. char* Sockaddr_print(struct Sockaddr* sockaddr, struct Allocator* alloc)
  160. {
  161. if (sockaddr->addrLen < Sockaddr_OVERHEAD
  162. || sockaddr->addrLen > Sockaddr_MAXSIZE + Sockaddr_OVERHEAD) {
  163. return "invalid";
  164. }
  165. if (sockaddr->type == Sockaddr_HANDLE) {
  166. // handle address
  167. uint32_t handle = Sockaddr_addrHandle(sockaddr);
  168. const char* target = "";
  169. if (sockaddr->addrLen > Sockaddr_OVERHEAD) {
  170. struct Sockaddr* sa2 = &sockaddr[1];
  171. if (sa2->addrLen != sockaddr->addrLen - Sockaddr_OVERHEAD) {
  172. target = "<invalid length>";
  173. } else {
  174. target = Sockaddr_print(sa2, alloc);
  175. }
  176. }
  177. String* out = String_printf(alloc, "Handle:%u/%s", handle, target);
  178. return out->bytes;
  179. }
  180. struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
  181. void* inAddr;
  182. uint16_t port;
  183. switch (addr->ss.ss_family) {
  184. case AF_INET:
  185. inAddr = &((struct sockaddr_in*) &addr->ss)->sin_addr;
  186. port = Endian_bigEndianToHost16(((struct sockaddr_in*)&addr->ss)->sin_port);
  187. break;
  188. case AF_INET6:
  189. inAddr = &((struct sockaddr_in6*) &addr->ss)->sin6_addr;
  190. port = Endian_bigEndianToHost16(((struct sockaddr_in6*)&addr->ss)->sin6_port);
  191. break;
  192. default: {
  193. uint8_t buff[Sockaddr_MAXSIZE * 2 + 1] = {0};
  194. Hex_encode(buff, sizeof(buff), (uint8_t*)sockaddr, sockaddr->addrLen);
  195. String* out = String_printf(alloc, "unknown (%s)", buff);
  196. return out->bytes;
  197. }
  198. };
  199. #define BUFF_SZ 64
  200. char printedAddr[BUFF_SZ] = {0};
  201. int ret = Rffi_inet_ntop(addr->ss.ss_family == AF_INET6, inAddr, printedAddr, BUFF_SZ - 1);
  202. if (ret != 0) {
  203. return "invalid";
  204. }
  205. char printedPrefix[16] = {0};
  206. if (addr->pub.flags & Sockaddr_flags_PREFIX) {
  207. snprintf(printedPrefix, 15, "/%u", addr->pub.prefix);
  208. }
  209. char printedPort[16] = {0};
  210. if (port) {
  211. snprintf(printedPort, 15, ":%u", port);
  212. }
  213. char finalAddr[128] = {0};
  214. const char* format = (port && addr->ss.ss_family == AF_INET6) ? "[%s%s]%s" : "%s%s%s";
  215. snprintf(finalAddr, 127, format, printedAddr, printedPrefix, printedPort);
  216. int totalLength = CString_strlen(finalAddr) + 1;
  217. char* out = Allocator_calloc(alloc, totalLength, 1);
  218. Bits_memcpy(out, finalAddr, totalLength);
  219. return out;
  220. }
  221. static uint16_t* getPortPtr(struct Sockaddr* sockaddr)
  222. {
  223. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  224. return NULL;
  225. }
  226. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  227. switch (sa->ss.ss_family) {
  228. case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
  229. case AF_INET6: return &((struct sockaddr_in6*)&sa->ss)->sin6_port;
  230. }
  231. return NULL;
  232. }
  233. int Sockaddr_getPort(const struct Sockaddr* sockaddr)
  234. {
  235. const uint16_t* pp = getPortPtr((struct Sockaddr*) sockaddr);
  236. return (pp) ? Endian_bigEndianToHost16(*pp) : -1;
  237. }
  238. int Sockaddr_setPort(struct Sockaddr* sockaddr, uint16_t port)
  239. {
  240. uint16_t* pp = getPortPtr(sockaddr);
  241. if (pp) {
  242. *pp = Endian_hostToBigEndian16(port);
  243. return 0;
  244. }
  245. return -1;
  246. }
  247. int Sockaddr_getAddress(struct Sockaddr* sockaddr, void* addrPtr)
  248. {
  249. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  250. return -1;
  251. }
  252. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  253. if (addrPtr) {
  254. void** ap = (void**) addrPtr;
  255. switch (sa->ss.ss_family) {
  256. case AF_INET: *ap = &((struct sockaddr_in*)&sa->ss)->sin_addr; break;
  257. case AF_INET6: *ap = &((struct sockaddr_in6*)&sa->ss)->sin6_addr; break;
  258. }
  259. }
  260. switch (sa->ss.ss_family) {
  261. case AF_INET: return 4;
  262. case AF_INET6: return 16;
  263. }
  264. return -1;
  265. }
  266. const int Sockaddr_AF_INET = AF_INET;
  267. const int Sockaddr_AF_INET6 = AF_INET6;
  268. int Sockaddr_getFamily(const struct Sockaddr* sockaddr)
  269. {
  270. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  271. return -1;
  272. }
  273. const struct Sockaddr_pvt* sa = (const struct Sockaddr_pvt*) sockaddr;
  274. return sa->ss.ss_family;
  275. }
  276. struct Sockaddr* Sockaddr_initFromBytes(struct Sockaddr_storage* out, const uint8_t* bytes, int addrFamily)
  277. {
  278. switch (addrFamily) {
  279. case AF_INET: {
  280. struct Sockaddr_in_pvt* in = (struct Sockaddr_in_pvt*) out;
  281. Bits_memset(in, 0, sizeof *in);
  282. in->si.sin_family = AF_INET;
  283. Bits_memcpy(&in->si.sin_addr, bytes, 4);
  284. in->pub.addrLen = sizeof(struct Sockaddr_in_pvt);
  285. break;
  286. }
  287. case AF_INET6: {
  288. struct Sockaddr_in6_pvt* in = (struct Sockaddr_in6_pvt*) out;
  289. Bits_memset(in, 0, sizeof *in);
  290. in->si.sin6_family = AF_INET6;
  291. Bits_memcpy(&in->si.sin6_addr, bytes, 16);
  292. in->pub.addrLen = sizeof(struct Sockaddr_in6_pvt);
  293. break;
  294. }
  295. default: Assert_failure("unrecognized address type [%d]", addrFamily);
  296. }
  297. return &out->addr;
  298. }
  299. struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allocator* alloc)
  300. {
  301. struct Sockaddr_storage ss;
  302. struct Sockaddr* sa = Sockaddr_initFromBytes(&ss, bytes, addrFamily);
  303. return Sockaddr_clone(sa, alloc);
  304. }
  305. void Sockaddr_normalizeNative(void* nativeSockaddr)
  306. {
  307. #if defined(freebsd) || defined(openbsd) || defined(netbsd) || defined(darwin)
  308. ((struct sockaddr*)nativeSockaddr)->sa_len = 0;
  309. #endif
  310. }
  311. uint32_t Sockaddr_hash(const struct Sockaddr* addr)
  312. {
  313. return Hash_compute((uint8_t*)addr, addr->addrLen);
  314. }
  315. void Sockaddr_asIp6(uint8_t addrOut[static 16], const struct Sockaddr* sockaddr)
  316. {
  317. Bits_memset(addrOut, 0, 16);
  318. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  319. // Corrupt sockaddr, whatever dude
  320. addrOut[0] = 0xff;
  321. addrOut[1] = 0xfc;
  322. int len = sockaddr->addrLen;
  323. Bits_memcpy(&addrOut[16-len], &sockaddr, len);
  324. }
  325. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  326. Bits_memset(addrOut, 0, 16);
  327. switch (sa->ss.ss_family) {
  328. case AF_INET: {
  329. // IPv4 in 6
  330. addrOut[10] = 0xff;
  331. addrOut[11] = 0xff;
  332. Bits_memcpy(&addrOut[12], &((struct sockaddr_in*)&sa->ss)->sin_addr, 4);
  333. break;
  334. }
  335. case AF_INET6: {
  336. // Normal IPv6
  337. Bits_memcpy(addrOut, &((struct sockaddr_in6*)&sa->ss)->sin6_addr, 16);
  338. break;
  339. }
  340. default: {
  341. uint16_t len = sa->pub.addrLen - Sockaddr_OVERHEAD;
  342. if (len <= 14) {
  343. addrOut[0] = 0xff;
  344. addrOut[1] = 0xfe;
  345. Bits_memcpy(&addrOut[16-len], &sa->ss, len);
  346. } else {
  347. uint8_t hash[32];
  348. crypto_hash_sha256(hash, (uint8_t*) &sa->ss, len);
  349. addrOut[0] = 0xff;
  350. addrOut[1] = 0xff;
  351. Bits_memcpy(&addrOut[2], hash, 14);
  352. }
  353. }
  354. }
  355. }
  356. int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
  357. {
  358. return Bits_memcmp(a, b, a->addrLen);
  359. }
  360. uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr)
  361. {
  362. if (addr->addrLen != sizeof(struct Sockaddr) || addr->type != Sockaddr_HANDLE) {
  363. return Sockaddr_addrHandle_INVALID;
  364. }
  365. uint32_t handle;
  366. Bits_memcpy(&handle, &((uint8_t*)addr)[4], 4);
  367. return handle;
  368. }
  369. void Sockaddr_addrFromHandle(struct Sockaddr* addr, uint32_t handle)
  370. {
  371. Assert_true(handle != Sockaddr_addrHandle_INVALID);
  372. Bits_memset(addr, 0, sizeof(struct Sockaddr));
  373. addr->type = Sockaddr_HANDLE;
  374. addr->addrLen = sizeof(struct Sockaddr);
  375. Bits_memcpy(&((uint8_t*)addr)[4], &handle, 4);
  376. }