Sockaddr.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  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 "exception/Err.h"
  16. #include "rust/cjdns_sys/Rffi.h"
  17. #include "benc/String.h"
  18. #include "memory/Allocator.h"
  19. #include "util/platform/Sockaddr.h"
  20. #include "util/AddrTools.h"
  21. #include "util/CString.h"
  22. #include "util/Bits.h"
  23. #include "util/Hex.h"
  24. #include "util/Hash.h"
  25. #include "util/Base10.h"
  26. #include "wire/Message.h"
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <stddef.h>
  30. #include <stdint.h>
  31. #include <netinet/in.h>
  32. struct Sockaddr_pvt
  33. {
  34. struct Sockaddr pub;
  35. struct sockaddr_storage ss;
  36. };
  37. void Sockaddr_assertions(void);
  38. void Sockaddr_assertions() {
  39. Assert_compileTime(sizeof(struct Sockaddr) == 8);
  40. Assert_compileTime(sizeof(struct sockaddr_storage) == 128);
  41. Assert_compileTime(sizeof(struct Sockaddr_pvt) == 128+8);
  42. Assert_compileTime(sizeof(struct Sockaddr_storage) == 128+8);
  43. }
  44. struct Sockaddr_in_pvt
  45. {
  46. struct Sockaddr pub;
  47. struct sockaddr_in si;
  48. };
  49. struct Sockaddr_in6_pvt
  50. {
  51. struct Sockaddr pub;
  52. struct sockaddr_in6 si;
  53. };
  54. typedef struct Sockaddr_eth_pvt
  55. {
  56. struct Sockaddr pub;
  57. uint16_t zero;
  58. uint8_t mac[6];
  59. } Sockaddr_eth_pvt_t;
  60. Assert_compileTime(sizeof(Sockaddr_eth_pvt_t) == 16);
  61. const struct Sockaddr* const Sockaddr_LOOPBACK_be =
  62. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  63. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  64. .si = {
  65. .sin_family = AF_INET,
  66. .sin_addr = { .s_addr = 0x7f000001 }
  67. }
  68. });
  69. const struct Sockaddr* const Sockaddr_LOOPBACK_le =
  70. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  71. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  72. .si = {
  73. .sin_family = AF_INET,
  74. .sin_addr = { .s_addr = 0x0100007f }
  75. }
  76. });
  77. const struct Sockaddr* const Sockaddr_LOOPBACK6 =
  78. (const struct Sockaddr*) &((const struct Sockaddr_in6_pvt) {
  79. .pub = { .addrLen = sizeof(struct Sockaddr_in6_pvt) },
  80. .si = {
  81. .sin6_family = AF_INET6,
  82. .sin6_addr = { .s6_addr = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
  83. }
  84. });
  85. int Sockaddr_getPrefix(struct Sockaddr* addr)
  86. {
  87. if (addr->flags & Sockaddr_flags_PREFIX) {
  88. return addr->prefix;
  89. }
  90. int af = Sockaddr_getFamily(addr);
  91. if (af == Sockaddr_AF_INET) {
  92. return 32;
  93. } else if (af == Sockaddr_AF_INET6) {
  94. return 128;
  95. } else {
  96. return -1;
  97. }
  98. }
  99. int Sockaddr_parse(const char* input, struct Sockaddr_storage* out)
  100. {
  101. struct Sockaddr_storage unusedOut;
  102. if (!out) {
  103. out = &unusedOut;
  104. }
  105. uint8_t buff[64] = {0};
  106. if (CString_strlen(input) > 63) {
  107. return -1;
  108. }
  109. CString_safeStrncpy(buff, input, 63);
  110. if (CString_strlen(buff) == 17) {
  111. // 17 bytes long, try it as a MAC
  112. Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
  113. Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) out;
  114. if (AddrTools_parseMac(eth->mac, buff) == 0) {
  115. out->addr.addrLen = sizeof *eth;
  116. out->addr.type = Sockaddr_ETHERNET;
  117. return 0;
  118. }
  119. // not a MaC, keep trying, lots of things are 17 bytes.
  120. }
  121. int64_t port = 0;
  122. char* lastColon = CString_strrchr(buff, ':');
  123. char* firstColon = CString_strchr(buff, ':');
  124. char* bracket = CString_strchr(buff, ']');
  125. if (!lastColon) {
  126. // ipv4, no port
  127. } else if (lastColon != firstColon && (!bracket || lastColon < bracket)) {
  128. // ipv6, no port
  129. } else {
  130. if (bracket && lastColon != &bracket[1]) { return -1; }
  131. if (Base10_fromString(&lastColon[1], &port)) { return -1; }
  132. if (port > 65535) { return -1; }
  133. *lastColon = '\0';
  134. }
  135. if (bracket) {
  136. *bracket = '\0';
  137. if (buff[0] != '[') { return -1; }
  138. } else if (buff[0] == '[') { return -1; }
  139. int64_t prefix = -1;
  140. char* slash = CString_strchr(buff, '/');
  141. if (slash) {
  142. *slash = '\0';
  143. if (!slash[1]) { return -1; }
  144. if (Base10_fromString(&slash[1], &prefix)) { return -1; }
  145. }
  146. Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
  147. if (lastColon != firstColon) {
  148. // ipv6
  149. struct sockaddr_in6* in6 = (struct sockaddr_in6*) Sockaddr_asNative(&out->addr);
  150. if (Rffi_inet_pton(1, (char*) ((buff[0] == '[') ? &buff[1] : buff), (uint8_t*) &in6->sin6_addr)) {
  151. return -1;
  152. }
  153. out->addr.addrLen = sizeof(struct sockaddr_in6) + Sockaddr_OVERHEAD;
  154. in6->sin6_port = Endian_hostToBigEndian16(port);
  155. in6->sin6_family = AF_INET6;
  156. } else {
  157. struct sockaddr_in* in = ((struct sockaddr_in*) Sockaddr_asNative(&out->addr));
  158. if (Rffi_inet_pton(0, (char*) buff, (uint8_t*) &in->sin_addr)) {
  159. return -1;
  160. }
  161. out->addr.addrLen = sizeof(struct sockaddr_in) + Sockaddr_OVERHEAD;
  162. in->sin_port = Endian_hostToBigEndian16(port);
  163. in->sin_family = AF_INET;
  164. }
  165. if (prefix != -1) {
  166. if (prefix < 0 || prefix > 128) { return -1; }
  167. if (Sockaddr_getFamily(&out->addr) == Sockaddr_AF_INET && prefix > 32) { return -1; }
  168. out->addr.prefix = prefix;
  169. out->addr.flags |= Sockaddr_flags_PREFIX;
  170. }
  171. return 0;
  172. }
  173. struct Sockaddr* Sockaddr_clone(const struct Sockaddr* addr, struct Allocator* alloc)
  174. {
  175. struct Sockaddr* out = Allocator_malloc(alloc, addr->addrLen);
  176. Bits_memcpy(out, addr, addr->addrLen);
  177. return out;
  178. }
  179. char* Sockaddr_print(struct Sockaddr* sockaddr, struct Allocator* alloc)
  180. {
  181. if (sockaddr->addrLen < Sockaddr_OVERHEAD
  182. || sockaddr->addrLen > Sockaddr_MAXSIZE + Sockaddr_OVERHEAD) {
  183. return "invalid";
  184. }
  185. if (sockaddr->type == Sockaddr_HANDLE) {
  186. // handle address
  187. uint32_t handle = Sockaddr_addrHandle(sockaddr);
  188. const char* target = "";
  189. if (sockaddr->addrLen > Sockaddr_OVERHEAD) {
  190. struct Sockaddr* sa2 = &sockaddr[1];
  191. if (sa2->addrLen != sockaddr->addrLen - Sockaddr_OVERHEAD) {
  192. target = "<invalid length>";
  193. } else {
  194. target = Sockaddr_print(sa2, alloc);
  195. }
  196. }
  197. String* out = String_printf(alloc, "Handle:%u/%s", handle, target);
  198. return out->bytes;
  199. }
  200. if (sockaddr->type == Sockaddr_ETHERNET) {
  201. if (sockaddr->addrLen != sizeof(Sockaddr_eth_pvt_t)) {
  202. return "eth/invalid";
  203. }
  204. Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) sockaddr;
  205. String* out = String_printf(alloc, "%02x:%02x:%02x:%02x:%02x:%02x",
  206. eth->mac[0], eth->mac[1], eth->mac[2], eth->mac[3], eth->mac[4], eth->mac[5]);
  207. return out->bytes;
  208. }
  209. struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
  210. void* inAddr;
  211. uint16_t port;
  212. switch (addr->ss.ss_family) {
  213. case AF_INET:
  214. inAddr = &((struct sockaddr_in*) &addr->ss)->sin_addr;
  215. port = Endian_bigEndianToHost16(((struct sockaddr_in*)&addr->ss)->sin_port);
  216. break;
  217. case AF_INET6:
  218. inAddr = &((struct sockaddr_in6*) &addr->ss)->sin6_addr;
  219. port = Endian_bigEndianToHost16(((struct sockaddr_in6*)&addr->ss)->sin6_port);
  220. break;
  221. default: {
  222. uint8_t buff[Sockaddr_MAXSIZE * 2 + 1] = {0};
  223. Hex_encode(buff, sizeof(buff), (uint8_t*)sockaddr, sockaddr->addrLen);
  224. String* out = String_printf(alloc, "unknown (%s)", buff);
  225. return out->bytes;
  226. }
  227. };
  228. #define BUFF_SZ 64
  229. char printedAddr[BUFF_SZ] = {0};
  230. int ret = Rffi_inet_ntop(addr->ss.ss_family == AF_INET6, inAddr, printedAddr, BUFF_SZ - 1);
  231. if (ret != 0) {
  232. return "invalid";
  233. }
  234. char printedPrefix[16] = {0};
  235. if (addr->pub.flags & Sockaddr_flags_PREFIX) {
  236. snprintf(printedPrefix, 15, "/%u", addr->pub.prefix);
  237. }
  238. char printedPort[16] = {0};
  239. if (port) {
  240. snprintf(printedPort, 15, ":%u", port);
  241. }
  242. char finalAddr[128] = {0};
  243. const char* format = (port && addr->ss.ss_family == AF_INET6) ? "[%s%s]%s" : "%s%s%s";
  244. snprintf(finalAddr, 127, format, printedAddr, printedPrefix, printedPort);
  245. int totalLength = CString_strlen(finalAddr) + 1;
  246. char* out = Allocator_calloc(alloc, totalLength, 1);
  247. Bits_memcpy(out, finalAddr, totalLength);
  248. return out;
  249. }
  250. static uint16_t* getPortPtr(struct Sockaddr* sockaddr)
  251. {
  252. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  253. return NULL;
  254. }
  255. if (sockaddr->type != Sockaddr_PLATFORM) {
  256. return NULL;
  257. }
  258. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  259. switch (sa->ss.ss_family) {
  260. case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
  261. case AF_INET6: return &((struct sockaddr_in6*)&sa->ss)->sin6_port;
  262. }
  263. return NULL;
  264. }
  265. int Sockaddr_getPort(const struct Sockaddr* sockaddr)
  266. {
  267. const uint16_t* pp = getPortPtr((struct Sockaddr*) sockaddr);
  268. return (pp) ? Endian_bigEndianToHost16(*pp) : -1;
  269. }
  270. int Sockaddr_getPort_fromRust(const struct Sockaddr* sockaddr)
  271. {
  272. return Sockaddr_getPort(sockaddr);
  273. }
  274. int Sockaddr_setPort(struct Sockaddr* sockaddr, uint16_t port)
  275. {
  276. uint16_t* pp = getPortPtr(sockaddr);
  277. if (pp) {
  278. *pp = Endian_hostToBigEndian16(port);
  279. return 0;
  280. }
  281. return -1;
  282. }
  283. int Sockaddr_setPort_fromRust(struct Sockaddr* sockaddr, uint16_t port)
  284. {
  285. return Sockaddr_setPort(sockaddr, port);
  286. }
  287. int Sockaddr_getAddress(struct Sockaddr* sockaddr, void* addrPtr)
  288. {
  289. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  290. return -1;
  291. }
  292. if (sockaddr->type != Sockaddr_PLATFORM) {
  293. return -2;
  294. }
  295. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  296. if (addrPtr) {
  297. void** ap = (void**) addrPtr;
  298. switch (sa->ss.ss_family) {
  299. case AF_INET: *ap = &((struct sockaddr_in*)&sa->ss)->sin_addr; break;
  300. case AF_INET6: *ap = &((struct sockaddr_in6*)&sa->ss)->sin6_addr; break;
  301. }
  302. }
  303. switch (sa->ss.ss_family) {
  304. case AF_INET: return 4;
  305. case AF_INET6: return 16;
  306. }
  307. return -1;
  308. }
  309. const int Sockaddr_AF_INET = AF_INET;
  310. const int Sockaddr_AF_INET6 = AF_INET6;
  311. int Sockaddr_getFamily(const struct Sockaddr* sockaddr)
  312. {
  313. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  314. return -1;
  315. }
  316. if (sockaddr->type != Sockaddr_PLATFORM) {
  317. return -2;
  318. }
  319. const struct Sockaddr_pvt* sa = (const struct Sockaddr_pvt*) sockaddr;
  320. return sa->ss.ss_family;
  321. }
  322. int Sockaddr_getFamily_fromRust(const struct Sockaddr* sockaddr)
  323. {
  324. return Sockaddr_getFamily(sockaddr);
  325. }
  326. struct Sockaddr* Sockaddr_initFromEth(struct Sockaddr_storage* out, const uint8_t mac[static 6]) {
  327. Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) out;
  328. Bits_memset(eth, 0, sizeof *eth);
  329. Bits_memcpy(eth->mac, mac, 6);
  330. eth->pub.addrLen = sizeof *eth;
  331. eth->pub.type = Sockaddr_ETHERNET;
  332. if (mac[0] == 0xff) {
  333. eth->pub.flags |= Sockaddr_flags_BCAST;
  334. }
  335. return &out->addr;
  336. }
  337. int Sockaddr_getMac(uint8_t out[static 6], const struct Sockaddr* sockaddr) {
  338. if (sockaddr->addrLen != sizeof(Sockaddr_eth_pvt_t) || sockaddr->type != Sockaddr_ETHERNET) {
  339. return -1;
  340. }
  341. Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) sockaddr;
  342. Bits_memcpy(out, eth->mac, 6);
  343. return 0;
  344. }
  345. struct Sockaddr* Sockaddr_initFromBytes(struct Sockaddr_storage* out, const uint8_t* bytes, int addrFamily)
  346. {
  347. switch (addrFamily) {
  348. case AF_INET: {
  349. struct Sockaddr_in_pvt* in = (struct Sockaddr_in_pvt*) out;
  350. Bits_memset(in, 0, sizeof *in);
  351. in->si.sin_family = AF_INET;
  352. Bits_memcpy(&in->si.sin_addr, bytes, 4);
  353. in->pub.addrLen = sizeof(struct Sockaddr_in_pvt);
  354. break;
  355. }
  356. case AF_INET6: {
  357. struct Sockaddr_in6_pvt* in = (struct Sockaddr_in6_pvt*) out;
  358. Bits_memset(in, 0, sizeof *in);
  359. in->si.sin6_family = AF_INET6;
  360. Bits_memcpy(&in->si.sin6_addr, bytes, 16);
  361. in->pub.addrLen = sizeof(struct Sockaddr_in6_pvt);
  362. break;
  363. }
  364. default: Assert_failure("unrecognized address type [%d]", addrFamily);
  365. }
  366. return &out->addr;
  367. }
  368. Sockaddr_t* Sockaddr_initFromBytes_fromRust(
  369. struct Sockaddr_storage* out,
  370. const uint8_t* bytes,
  371. int addrFamily
  372. ) {
  373. return Sockaddr_initFromBytes(out, bytes, addrFamily);
  374. }
  375. struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allocator* alloc)
  376. {
  377. struct Sockaddr_storage ss;
  378. struct Sockaddr* sa = Sockaddr_initFromBytes(&ss, bytes, addrFamily);
  379. return Sockaddr_clone(sa, alloc);
  380. }
  381. uint32_t Sockaddr_hash(const struct Sockaddr* addr)
  382. {
  383. return Hash_compute((uint8_t*)addr, addr->addrLen);
  384. }
  385. void Sockaddr_asIp6(uint8_t addrOut[static 16], const struct Sockaddr* sockaddr)
  386. {
  387. Bits_memset(addrOut, 0, 16);
  388. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  389. // Corrupt sockaddr, whatever dude
  390. addrOut[0] = 0xff;
  391. addrOut[1] = 0xfc;
  392. int len = sockaddr->addrLen;
  393. Bits_memcpy(&addrOut[16-len], &sockaddr, len);
  394. }
  395. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  396. Bits_memset(addrOut, 0, 16);
  397. switch (Sockaddr_getFamily(sockaddr)) {
  398. case AF_INET: {
  399. // IPv4 in 6
  400. addrOut[10] = 0xff;
  401. addrOut[11] = 0xff;
  402. Bits_memcpy(&addrOut[12], &((struct sockaddr_in*)&sa->ss)->sin_addr, 4);
  403. break;
  404. }
  405. case AF_INET6: {
  406. // Normal IPv6
  407. Bits_memcpy(addrOut, &((struct sockaddr_in6*)&sa->ss)->sin6_addr, 16);
  408. break;
  409. }
  410. default: {
  411. uint16_t len = sa->pub.addrLen - Sockaddr_OVERHEAD;
  412. if (len <= 14) {
  413. addrOut[0] = 0xff;
  414. addrOut[1] = 0xfe - sockaddr->type;
  415. Bits_memcpy(&addrOut[16-len], &sa->ss, len);
  416. } else {
  417. uint8_t hash[32];
  418. Rffi_crypto_hash_sha256(hash, (uint8_t*) &sa->ss, len);
  419. addrOut[0] = 0xff;
  420. addrOut[1] = 0xff;
  421. Bits_memcpy(&addrOut[2], hash, 14);
  422. }
  423. }
  424. }
  425. }
  426. void Sockaddr_asIp6_fromRust(uint8_t addrOut[static 16], const struct Sockaddr* sockaddr)
  427. {
  428. Sockaddr_asIp6(addrOut, sockaddr);
  429. }
  430. int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
  431. {
  432. if (a->addrLen < b->addrLen) {
  433. return -1;
  434. } else if (a->addrLen > b->addrLen) {
  435. return 1;
  436. } else {
  437. return Bits_memcmp(a, b, a->addrLen);
  438. }
  439. }
  440. uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr)
  441. {
  442. if (addr->addrLen != sizeof(struct Sockaddr) || addr->type != Sockaddr_HANDLE) {
  443. return Sockaddr_addrHandle_INVALID;
  444. }
  445. uint32_t handle;
  446. Bits_memcpy(&handle, &((uint8_t*)addr)[4], 4);
  447. return handle;
  448. }
  449. uint32_t Sockaddr_addrHandle_fromRust(const Sockaddr_t* addr)
  450. {
  451. return Sockaddr_addrHandle(addr);
  452. }
  453. void Sockaddr_addrFromHandle(struct Sockaddr* addr, uint32_t handle)
  454. {
  455. Assert_true(handle != Sockaddr_addrHandle_INVALID);
  456. Bits_memset(addr, 0, sizeof(struct Sockaddr));
  457. addr->type = Sockaddr_HANDLE;
  458. addr->addrLen = sizeof(struct Sockaddr);
  459. Bits_memcpy(&((uint8_t*)addr)[4], &handle, 4);
  460. }
  461. Err_DEFUN Sockaddr_read(struct Sockaddr_storage* out, Message_t* readFrom) {
  462. if (Message_getLength(readFrom) < Sockaddr_OVERHEAD) {
  463. Err_raise(Message_getAlloc(readFrom),
  464. "Error: Message len [%d] too short to contain Sockaddr",
  465. Message_getLength(readFrom));
  466. }
  467. Err(Message_epop(readFrom, &out->addr, sizeof out->addr));
  468. if (out->addr.addrLen < Sockaddr_OVERHEAD) {
  469. Err_raise(Message_getAlloc(readFrom),
  470. "Invalid addrLen in Sockaddr: [%d]", out->addr.addrLen);
  471. }
  472. Err(Message_epop(readFrom, &out->nativeAddr, out->addr.addrLen - Sockaddr_OVERHEAD));
  473. return NULL;
  474. }
  475. Err_DEFUN Sockaddr_write(const struct Sockaddr* from, Message_t* writeTo) {
  476. return Message_epush(writeTo, from, from->addrLen);
  477. }