1
0

Sockaddr.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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 "util/events/libuv/UvWrapper.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 <stdio.h>
  25. #include <stdlib.h>
  26. #include <stddef.h>
  27. #include <stdint.h>
  28. struct Sockaddr_pvt
  29. {
  30. struct Sockaddr pub;
  31. struct sockaddr_storage ss;
  32. };
  33. struct Sockaddr_in_pvt
  34. {
  35. struct Sockaddr pub;
  36. struct sockaddr_in si;
  37. };
  38. struct Sockaddr_in6_pvt
  39. {
  40. struct Sockaddr pub;
  41. struct sockaddr_in6 si;
  42. };
  43. const struct Sockaddr* const Sockaddr_LOOPBACK_be =
  44. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  45. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  46. .si = {
  47. .sin_family = AF_INET,
  48. .sin_addr = { .s_addr = 0x7f000001 }
  49. }
  50. });
  51. const struct Sockaddr* const Sockaddr_LOOPBACK_le =
  52. (const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
  53. .pub = { .addrLen = sizeof(struct Sockaddr_in_pvt) },
  54. .si = {
  55. .sin_family = AF_INET,
  56. .sin_addr = { .s_addr = 0x0100007f }
  57. }
  58. });
  59. const struct Sockaddr* const Sockaddr_LOOPBACK6 =
  60. (const struct Sockaddr*) &((const struct Sockaddr_in6_pvt) {
  61. .pub = { .addrLen = sizeof(struct Sockaddr_in6_pvt) },
  62. .si = {
  63. .sin6_family = AF_INET6,
  64. .sin6_addr = { .s6_addr = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
  65. }
  66. });
  67. struct Sockaddr* Sockaddr_fromNative(const void* ss, int addrLen, struct Allocator* alloc)
  68. {
  69. struct Sockaddr_pvt* out = Allocator_calloc(alloc, addrLen + Sockaddr_OVERHEAD, 1);
  70. Bits_memcpy(&out->ss, ss, addrLen);
  71. out->pub.addrLen = addrLen + Sockaddr_OVERHEAD;
  72. Sockaddr_normalizeNative(&out->ss);
  73. return &out->pub;
  74. }
  75. int Sockaddr_getPrefix(struct Sockaddr* addr)
  76. {
  77. if (addr->flags & Sockaddr_flags_PREFIX) {
  78. return addr->prefix;
  79. }
  80. int af = Sockaddr_getFamily(addr);
  81. if (af == Sockaddr_AF_INET) {
  82. return 32;
  83. } else if (af == Sockaddr_AF_INET6) {
  84. return 128;
  85. } else {
  86. return -1;
  87. }
  88. }
  89. int Sockaddr_parse(const char* input, struct Sockaddr_storage* out)
  90. {
  91. struct Sockaddr_storage unusedOut;
  92. if (!out) {
  93. out = &unusedOut;
  94. }
  95. uint8_t buff[64] = {0};
  96. if (CString_strlen(input) > 63) {
  97. return -1;
  98. }
  99. CString_safeStrncpy(buff, input, 63);
  100. int64_t port = 0;
  101. char* lastColon = CString_strrchr(buff, ':');
  102. char* firstColon = CString_strchr(buff, ':');
  103. char* bracket = CString_strchr(buff, ']');
  104. if (!lastColon) {
  105. // ipv4, no port
  106. } else if (lastColon != firstColon && (!bracket || lastColon < bracket)) {
  107. // ipv6, no port
  108. } else {
  109. if (bracket && lastColon != &bracket[1]) { return -1; }
  110. if (Base10_fromString(&lastColon[1], &port)) { return -1; }
  111. if (port > 65535) { return -1; }
  112. *lastColon = '\0';
  113. }
  114. if (bracket) {
  115. *bracket = '\0';
  116. if (buff[0] != '[') { return -1; }
  117. } else if (buff[0] == '[') { return -1; }
  118. int64_t prefix = -1;
  119. char* slash = CString_strchr(buff, '/');
  120. if (slash) {
  121. *slash = '\0';
  122. if (!slash[1]) { return -1; }
  123. if (Base10_fromString(&slash[1], &prefix)) { return -1; }
  124. }
  125. Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
  126. if (lastColon != firstColon) {
  127. // ipv6
  128. struct sockaddr_in6* in6 = (struct sockaddr_in6*) Sockaddr_asNative(&out->addr);
  129. if (uv_inet_pton(AF_INET6, (char*) ((buff[0] == '[') ? &buff[1] : buff), &in6->sin6_addr)) {
  130. return -1;
  131. }
  132. out->addr.addrLen = sizeof(struct sockaddr_in6) + Sockaddr_OVERHEAD;
  133. in6->sin6_port = Endian_hostToBigEndian16(port);
  134. in6->sin6_family = AF_INET6;
  135. } else {
  136. struct sockaddr_in* in = ((struct sockaddr_in*) Sockaddr_asNative(&out->addr));
  137. if (uv_inet_pton(AF_INET, (char*) buff, &in->sin_addr)) {
  138. return -1;
  139. }
  140. out->addr.addrLen = sizeof(struct sockaddr_in) + Sockaddr_OVERHEAD;
  141. in->sin_port = Endian_hostToBigEndian16(port);
  142. in->sin_family = AF_INET;
  143. }
  144. if (prefix != -1) {
  145. if (prefix < 0 || prefix > 128) { return -1; }
  146. if (Sockaddr_getFamily(&out->addr) == Sockaddr_AF_INET && prefix > 32) { return -1; }
  147. out->addr.prefix = prefix;
  148. out->addr.flags |= Sockaddr_flags_PREFIX;
  149. }
  150. return 0;
  151. }
  152. struct Sockaddr* Sockaddr_clone(const struct Sockaddr* addr, struct Allocator* alloc)
  153. {
  154. struct Sockaddr* out = Allocator_malloc(alloc, addr->addrLen);
  155. Bits_memcpy(out, addr, addr->addrLen);
  156. return out;
  157. }
  158. char* Sockaddr_print(struct Sockaddr* sockaddr, struct Allocator* alloc)
  159. {
  160. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)
  161. || sockaddr->addrLen > Sockaddr_MAXSIZE + Sockaddr_OVERHEAD) {
  162. return "invalid";
  163. }
  164. struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
  165. void* inAddr;
  166. uint16_t port;
  167. switch (addr->ss.ss_family) {
  168. case AF_INET:
  169. inAddr = &((struct sockaddr_in*) &addr->ss)->sin_addr;
  170. port = Endian_bigEndianToHost16(((struct sockaddr_in*)&addr->ss)->sin_port);
  171. break;
  172. case AF_INET6:
  173. inAddr = &((struct sockaddr_in6*) &addr->ss)->sin6_addr;
  174. port = Endian_bigEndianToHost16(((struct sockaddr_in6*)&addr->ss)->sin6_port);
  175. break;
  176. default: {
  177. uint8_t buff[Sockaddr_MAXSIZE * 2 + 1] = {0};
  178. Hex_encode(buff, sizeof(buff), (uint8_t*)&addr->ss,
  179. sockaddr->addrLen - Sockaddr_OVERHEAD);
  180. String* out = String_printf(alloc, "unknown (%s)", buff);
  181. return out->bytes;
  182. }
  183. };
  184. #define BUFF_SZ 64
  185. char printedAddr[BUFF_SZ] = {0};
  186. int ret = uv_inet_ntop(addr->ss.ss_family, inAddr, printedAddr, BUFF_SZ - 1);
  187. if (ret != 0) {
  188. return "invalid";
  189. }
  190. char printedPrefix[16] = {0};
  191. if (addr->pub.flags & Sockaddr_flags_PREFIX) {
  192. snprintf(printedPrefix, 15, "/%u", addr->pub.prefix);
  193. }
  194. char printedPort[16] = {0};
  195. if (port) {
  196. snprintf(printedPort, 15, ":%u", port);
  197. }
  198. char finalAddr[128] = {0};
  199. const char* format = (port && addr->ss.ss_family == AF_INET6) ? "[%s%s]%s" : "%s%s%s";
  200. snprintf(finalAddr, 127, format, printedAddr, printedPrefix, printedPort);
  201. int totalLength = CString_strlen(finalAddr) + 1;
  202. char* out = Allocator_calloc(alloc, totalLength, 1);
  203. Bits_memcpy(out, finalAddr, totalLength);
  204. return out;
  205. }
  206. static uint16_t* getPortPtr(struct Sockaddr* sockaddr)
  207. {
  208. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  209. return NULL;
  210. }
  211. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  212. switch (sa->ss.ss_family) {
  213. case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
  214. case AF_INET6: return &((struct sockaddr_in6*)&sa->ss)->sin6_port;
  215. }
  216. return NULL;
  217. }
  218. int Sockaddr_getPort(struct Sockaddr* sockaddr)
  219. {
  220. uint16_t* pp = getPortPtr(sockaddr);
  221. return (pp) ? Endian_bigEndianToHost16(*pp) : -1;
  222. }
  223. int Sockaddr_setPort(struct Sockaddr* sockaddr, uint16_t port)
  224. {
  225. uint16_t* pp = getPortPtr(sockaddr);
  226. if (pp) {
  227. *pp = Endian_hostToBigEndian16(port);
  228. return 0;
  229. }
  230. return -1;
  231. }
  232. int Sockaddr_getAddress(struct Sockaddr* sockaddr, void* addrPtr)
  233. {
  234. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  235. return -1;
  236. }
  237. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  238. if (addrPtr) {
  239. void** ap = (void**) addrPtr;
  240. switch (sa->ss.ss_family) {
  241. case AF_INET: *ap = &((struct sockaddr_in*)&sa->ss)->sin_addr; break;
  242. case AF_INET6: *ap = &((struct sockaddr_in6*)&sa->ss)->sin6_addr; break;
  243. }
  244. }
  245. switch (sa->ss.ss_family) {
  246. case AF_INET: return 4;
  247. case AF_INET6: return 16;
  248. }
  249. return -1;
  250. }
  251. const int Sockaddr_AF_INET = AF_INET;
  252. const int Sockaddr_AF_INET6 = AF_INET6;
  253. int Sockaddr_getFamily(struct Sockaddr* sockaddr)
  254. {
  255. if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
  256. return -1;
  257. }
  258. struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
  259. return sa->ss.ss_family;
  260. }
  261. struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allocator* alloc)
  262. {
  263. struct sockaddr_storage ss;
  264. Bits_memset(&ss, 0, sizeof(struct sockaddr_storage));
  265. int addrLen;
  266. switch (addrFamily) {
  267. case AF_INET: {
  268. ss.ss_family = AF_INET;
  269. Bits_memcpy(&((struct sockaddr_in*)&ss)->sin_addr, bytes, 4);
  270. addrLen = sizeof(struct sockaddr_in);
  271. break;
  272. }
  273. case AF_INET6: {
  274. ss.ss_family = AF_INET6;
  275. Bits_memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr, bytes, 16);
  276. addrLen = sizeof(struct sockaddr_in6);
  277. break;
  278. }
  279. default: Assert_failure("unrecognized address type [%d]", addrFamily);
  280. }
  281. struct Sockaddr_pvt* out = Allocator_calloc(alloc, addrLen + Sockaddr_OVERHEAD, 1);
  282. Bits_memcpy(&out->ss, &ss, addrLen);
  283. out->pub.addrLen = addrLen + Sockaddr_OVERHEAD;
  284. return &out->pub;
  285. }
  286. void Sockaddr_normalizeNative(void* nativeSockaddr)
  287. {
  288. #if defined(freebsd) || defined(openbsd) || defined(netbsd) || defined(darwin)
  289. ((struct sockaddr*)nativeSockaddr)->sa_len = 0;
  290. #endif
  291. }
  292. uint32_t Sockaddr_hash(const struct Sockaddr* addr)
  293. {
  294. return Hash_compute((uint8_t*)addr, addr->addrLen);
  295. }
  296. int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
  297. {
  298. return Bits_memcmp(a, b, a->addrLen);
  299. }
  300. uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr)
  301. {
  302. if (addr->addrLen != sizeof(struct Sockaddr) || addr->type != Sockaddr_HANDLE) {
  303. return Sockaddr_addrHandle_INVALID;
  304. }
  305. uint32_t handle;
  306. Bits_memcpy(&handle, &((uint8_t*)addr)[4], 4);
  307. return handle;
  308. }
  309. void Sockaddr_addrFromHandle(struct Sockaddr* addr, uint32_t handle)
  310. {
  311. Assert_true(handle != Sockaddr_addrHandle_INVALID);
  312. Bits_memset(addr, 0, sizeof(struct Sockaddr));
  313. addr->type = Sockaddr_HANDLE;
  314. addr->addrLen = sizeof(struct Sockaddr);
  315. Bits_memcpy(&((uint8_t*)addr)[4], &handle, 4);
  316. }