sock_util.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "asprintf.h"
  9. #include "sock.h"
  10. #include "warnp.h"
  11. #include "sock_internal.h"
  12. #include "sock_util.h"
  13. #ifdef POSIXFAIL_INET_ADDRSTRLEN
  14. #define INET_ADDRSTRLEN 16
  15. #endif
  16. #ifdef POSIXFAIL_INET6_ADDRSTRLEN
  17. #define INET6_ADDRSTRLEN 46
  18. #endif
  19. /**
  20. * sock_addr_cmp(sa1, sa2):
  21. * Return non-zero iff the socket addresses ${sa1} and ${sa2} are different.
  22. */
  23. int
  24. sock_addr_cmp(const struct sock_addr * sa1, const struct sock_addr * sa2)
  25. {
  26. /* Family, socket type, and name length must match. */
  27. if ((sa1->ai_family != sa2->ai_family) ||
  28. (sa1->ai_socktype != sa2->ai_socktype) ||
  29. (sa1->namelen != sa2->namelen))
  30. return (1);
  31. /* The required length of the sockaddr must match. */
  32. if (memcmp(sa1->name, sa2->name, sa1->namelen) != 0)
  33. return (1);
  34. /* Everything matched. */
  35. return (0);
  36. }
  37. /**
  38. * sock_addr_dup(sa):
  39. * Duplicate the provided socket address.
  40. */
  41. struct sock_addr *
  42. sock_addr_dup(const struct sock_addr * sa)
  43. {
  44. struct sock_addr * sa2;
  45. /* Allocate a struct sock_addr and copy fields. */
  46. if ((sa2 = malloc(sizeof(struct sock_addr))) == NULL)
  47. goto err0;
  48. sa2->ai_family = sa->ai_family;
  49. sa2->ai_socktype = sa->ai_socktype;
  50. sa2->namelen = sa->namelen;
  51. /* Allocate and copy the sockaddr. */
  52. if ((sa2->name = malloc(sa2->namelen)) == NULL)
  53. goto err1;
  54. memcpy(sa2->name, sa->name, sa2->namelen);
  55. /* Success! */
  56. return (sa2);
  57. err1:
  58. free(sa2);
  59. err0:
  60. /* Failure! */
  61. return (NULL);
  62. }
  63. /**
  64. * sock_addr_duplist(sas):
  65. * Duplicate the provided list of socket addresses.
  66. */
  67. struct sock_addr **
  68. sock_addr_duplist(struct sock_addr * const * sas)
  69. {
  70. struct sock_addr ** sas2;
  71. size_t i;
  72. /* Count socket addresses. */
  73. for (i = 0; sas[i] != NULL; i++)
  74. continue;
  75. /* Allocate the list to hold addresses plus a NULL terminator. */
  76. if ((sas2 = malloc((i + 1) * sizeof(struct sock_addr *))) == NULL)
  77. goto err0;
  78. /* Duplicate addresses and NULL-terminate. */
  79. for (i = 0; sas[i] != NULL; i++) {
  80. if ((sas2[i] = sock_addr_dup(sas[i])) == NULL)
  81. goto err1;
  82. }
  83. sas2[i] = NULL;
  84. /* Success! */
  85. return (sas2);
  86. err1:
  87. /*
  88. * Regardless of how many addresses we managed to duplicate before
  89. * failing and being sent here, we have a valid socket address list,
  90. * since the erroring sock_addr_dup call NULL-terminated it for us;
  91. * so we can free it and its constituent addresses easily.
  92. */
  93. sock_addr_freelist(sas2);
  94. err0:
  95. /* Failure! */
  96. return (NULL);
  97. }
  98. /**
  99. * sock_addr_serialize(sa, buf, buflen):
  100. * Allocate a buffer and serialize the socket address ${sa} into it. Return
  101. * the buffer via ${buf} and its length via ${buflen}. The serialization is
  102. * machine and operating system dependent.
  103. */
  104. int
  105. sock_addr_serialize(const struct sock_addr * sa,
  106. uint8_t ** buf, size_t * buflen)
  107. {
  108. uint8_t * p;
  109. /* Compute buffer length and allocate buffer. */
  110. *buflen = 2 * sizeof(int) + sizeof(socklen_t) + sa->namelen;
  111. if ((p = *buf = malloc(*buflen)) == NULL)
  112. goto err0;
  113. /* Copy in data. */
  114. memcpy(p, &sa->ai_family, sizeof(int));
  115. p += sizeof(int);
  116. memcpy(p, &sa->ai_socktype, sizeof(int));
  117. p += sizeof(int);
  118. memcpy(p, &sa->namelen, sizeof(socklen_t));
  119. p += sizeof(socklen_t);
  120. memcpy(p, sa->name, sa->namelen);
  121. /* Success! */
  122. return (0);
  123. err0:
  124. /* Failure! */
  125. return (-1);
  126. }
  127. /**
  128. * sock_addr_deserialize(buf, buflen):
  129. * Deserialize the ${buflen}-byte serialized socket address from ${buf}.
  130. */
  131. struct sock_addr *
  132. sock_addr_deserialize(const uint8_t * buf, size_t buflen)
  133. {
  134. struct sock_addr * sa;
  135. /* Sanity check. */
  136. if (buflen < 2 * sizeof(int) + sizeof(socklen_t))
  137. goto err0;
  138. /* Allocate a structure and copy in fields. */
  139. if ((sa = malloc(sizeof(struct sock_addr))) == NULL)
  140. goto err0;
  141. memcpy(&sa->ai_family, buf, sizeof(int));
  142. buf += sizeof(int);
  143. memcpy(&sa->ai_socktype, buf, sizeof(int));
  144. buf += sizeof(int);
  145. memcpy(&sa->namelen, buf, sizeof(socklen_t));
  146. buf += sizeof(socklen_t);
  147. /* Allocate and copy the sockaddr. */
  148. if (buflen != 2 * sizeof(int) + sizeof(socklen_t) + sa->namelen)
  149. goto err1;
  150. if ((sa->name = malloc(sa->namelen)) == NULL)
  151. goto err1;
  152. memcpy(sa->name, buf, sa->namelen);
  153. /* Success! */
  154. return (sa);
  155. err1:
  156. free(sa);
  157. err0:
  158. /* Failure! */
  159. return (NULL);
  160. }
  161. /* Prettyprint an IPv4 address. */
  162. static char *
  163. prettyprint_ipv4(struct sockaddr * name, size_t namelen)
  164. {
  165. struct sockaddr_in sa_in;
  166. char addr[INET_ADDRSTRLEN];
  167. char * s;
  168. /* Check name length. */
  169. if (namelen != sizeof(struct sockaddr_in))
  170. return (NULL);
  171. /* Copy into buffer for alignment. */
  172. memcpy(&sa_in, name, namelen);
  173. /* Convert IP address to string. */
  174. if (inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof(addr)) == NULL)
  175. return (NULL);
  176. /* Construct address string. */
  177. if (asprintf(&s, "[%s]:%d", addr, ntohs(sa_in.sin_port)) == -1)
  178. return (NULL);
  179. /* Success! */
  180. return (s);
  181. }
  182. /* Prettyprint an IPv6 address. */
  183. static char *
  184. prettyprint_ipv6(struct sockaddr * name, size_t namelen)
  185. {
  186. struct sockaddr_in6 sa_in6;
  187. char addr[INET6_ADDRSTRLEN];
  188. char * s;
  189. /* Check name length. */
  190. if (namelen != sizeof(struct sockaddr_in6))
  191. return (NULL);
  192. /* Copy into buffer for alignment. */
  193. memcpy(&sa_in6, name, namelen);
  194. /* Convert IPv6 address to string. */
  195. if (inet_ntop(AF_INET6, &sa_in6.sin6_addr, addr, sizeof(addr)) == NULL)
  196. return (NULL);
  197. /* Construct address string. */
  198. if (asprintf(&s, "[%s]:%d", addr, ntohs(sa_in6.sin6_port)) == -1)
  199. return (NULL);
  200. /* Success! */
  201. return (s);
  202. }
  203. /* Prettyprint a UNIX address. */
  204. static char *
  205. prettyprint_unix(struct sockaddr_un * name)
  206. {
  207. /* Just strdup the path. */
  208. return (strdup(name->sun_path));
  209. }
  210. /**
  211. * sock_addr_prettyprint(sa):
  212. * Allocate and return a string in one of the forms
  213. * /path/to/unix/socket
  214. * [ip.v4.ad.dr]:port
  215. * [ipv6:add::ress]:port
  216. * representing the provided socket address.
  217. */
  218. char *
  219. sock_addr_prettyprint(const struct sock_addr * sa)
  220. {
  221. /* Handle different types of addresses differently. */
  222. switch (sa->ai_family) {
  223. case AF_INET:
  224. return (prettyprint_ipv4(sa->name, sa->namelen));
  225. case AF_INET6:
  226. return (prettyprint_ipv6(sa->name, sa->namelen));
  227. case AF_UNIX:
  228. return (prettyprint_unix((struct sockaddr_un *)(sa->name)));
  229. default:
  230. return (strdup("Unknown address"));
  231. }
  232. }
  233. /**
  234. * sock_addr_ensure_port(addr):
  235. * Allocate a new string to serve as the address for sock_resolve().
  236. * If ${addr} contains a port number or is the address of a Unix domain
  237. * socket, duplicate that string; if not, add a port number of ":0".
  238. */
  239. char *
  240. sock_addr_ensure_port(const char * addr)
  241. {
  242. char * bind_addr;
  243. char * cr;
  244. /* Sanity check. */
  245. assert(addr != NULL);
  246. /* Where is the right-most colon in $addr? */
  247. cr = strrchr(addr, ':');
  248. /* Figure out what type of address $addr is. */
  249. if (cr == addr) {
  250. /*
  251. * If the right-most colon is the first char, it's not a valid
  252. * address, but we'll strdup it anyway.
  253. */
  254. bind_addr = strdup(addr);
  255. } else if (addr[0] == '/') {
  256. /* It's a Unix domain socket and doesn't need a port number. */
  257. bind_addr = strdup(addr);
  258. } else if (addr[0] != '[') {
  259. /* It's a hostname... */
  260. if (cr == NULL) {
  261. /* ... without any port number, so we add ":0". */
  262. if (asprintf(&bind_addr, "%s:0", addr) == -1)
  263. goto err0;
  264. } else {
  265. /* ... which already has a port number. */
  266. bind_addr = strdup(addr);
  267. }
  268. } else {
  269. /* addr[0] == '[', so it's an address... */
  270. if ((cr == NULL) || (cr[-1] != ']')) {
  271. /* ... without a port number, so we add ":0". */
  272. if (asprintf(&bind_addr, "%s:0", addr) == -1)
  273. goto err0;
  274. } else {
  275. /* ... which already has a port number. */
  276. bind_addr = strdup(addr);
  277. }
  278. }
  279. /* Success! */
  280. return (bind_addr);
  281. err0:
  282. /* Failure! */
  283. return (NULL);
  284. }
  285. /**
  286. * sock_addr_validate(addr):
  287. * Check that ${addr} is syntactically valid, but do not perform any address
  288. * resolution.
  289. */
  290. int
  291. sock_addr_validate(const char * addr)
  292. {
  293. /* Sanity check. */
  294. assert(addr != NULL);
  295. /* Check for an empty address. */
  296. if (strlen(addr) == 0) {
  297. warn0("Empty socket address.");
  298. goto err0;
  299. }
  300. /* If this isn't a UNIX socket address, check for a missing hostname. */
  301. if ((addr[0] != '/') && (addr[0] == ':')) {
  302. warn0("No host in \"%s\"", addr);
  303. goto err0;
  304. }
  305. /* Success! */
  306. return (0);
  307. err0:
  308. /* Failure! */
  309. return (-1);
  310. }