addr.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Copyright 2009, Oracle. All rights reserved.
  3. *
  4. * Convert socket addresses to presentation addresses and universal
  5. * addresses, and vice versa.
  6. *
  7. * Universal addresses are introduced by RFC 1833 and further refined by
  8. * recent RFCs describing NFSv4. The universal address format is part
  9. * of the external (network) interface provided by rpcbind version 3
  10. * and 4, and by NFSv4. Such an address is a string containing a
  11. * presentation format IP address followed by a port number in
  12. * "hibyte.lobyte" format.
  13. *
  14. * IPv6 addresses can also include a scope ID, typically denoted by
  15. * a '%' followed by a device name or a non-negative integer. Refer to
  16. * RFC 4291, Section 2.2 for details on IPv6 presentation formats.
  17. */
  18. #include <net/ipv6.h>
  19. #include <linux/sunrpc/clnt.h>
  20. #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  21. static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
  22. char *buf, const int buflen)
  23. {
  24. const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  25. const struct in6_addr *addr = &sin6->sin6_addr;
  26. /*
  27. * RFC 4291, Section 2.2.2
  28. *
  29. * Shorthanded ANY address
  30. */
  31. if (ipv6_addr_any(addr))
  32. return snprintf(buf, buflen, "::");
  33. /*
  34. * RFC 4291, Section 2.2.2
  35. *
  36. * Shorthanded loopback address
  37. */
  38. if (ipv6_addr_loopback(addr))
  39. return snprintf(buf, buflen, "::1");
  40. /*
  41. * RFC 4291, Section 2.2.3
  42. *
  43. * Special presentation address format for mapped v4
  44. * addresses.
  45. */
  46. if (ipv6_addr_v4mapped(addr))
  47. return snprintf(buf, buflen, "::ffff:%pI4",
  48. &addr->s6_addr32[3]);
  49. /*
  50. * RFC 4291, Section 2.2.1
  51. */
  52. return snprintf(buf, buflen, "%pI6c", addr);
  53. }
  54. static size_t rpc_ntop6(const struct sockaddr *sap,
  55. char *buf, const size_t buflen)
  56. {
  57. const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  58. char scopebuf[IPV6_SCOPE_ID_LEN];
  59. size_t len;
  60. int rc;
  61. len = rpc_ntop6_noscopeid(sap, buf, buflen);
  62. if (unlikely(len == 0))
  63. return len;
  64. if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
  65. !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
  66. return len;
  67. rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u",
  68. IPV6_SCOPE_DELIMITER, sin6->sin6_scope_id);
  69. if (unlikely((size_t)rc > sizeof(scopebuf)))
  70. return 0;
  71. len += rc;
  72. if (unlikely(len > buflen))
  73. return 0;
  74. strcat(buf, scopebuf);
  75. return len;
  76. }
  77. #else /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
  78. static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
  79. char *buf, const int buflen)
  80. {
  81. return 0;
  82. }
  83. static size_t rpc_ntop6(const struct sockaddr *sap,
  84. char *buf, const size_t buflen)
  85. {
  86. return 0;
  87. }
  88. #endif /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
  89. static int rpc_ntop4(const struct sockaddr *sap,
  90. char *buf, const size_t buflen)
  91. {
  92. const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
  93. return snprintf(buf, buflen, "%pI4", &sin->sin_addr);
  94. }
  95. /**
  96. * rpc_ntop - construct a presentation address in @buf
  97. * @sap: socket address
  98. * @buf: construction area
  99. * @buflen: size of @buf, in bytes
  100. *
  101. * Plants a %NUL-terminated string in @buf and returns the length
  102. * of the string, excluding the %NUL. Otherwise zero is returned.
  103. */
  104. size_t rpc_ntop(const struct sockaddr *sap, char *buf, const size_t buflen)
  105. {
  106. switch (sap->sa_family) {
  107. case AF_INET:
  108. return rpc_ntop4(sap, buf, buflen);
  109. case AF_INET6:
  110. return rpc_ntop6(sap, buf, buflen);
  111. }
  112. return 0;
  113. }
  114. EXPORT_SYMBOL_GPL(rpc_ntop);
  115. static size_t rpc_pton4(const char *buf, const size_t buflen,
  116. struct sockaddr *sap, const size_t salen)
  117. {
  118. struct sockaddr_in *sin = (struct sockaddr_in *)sap;
  119. u8 *addr = (u8 *)&sin->sin_addr.s_addr;
  120. if (buflen > INET_ADDRSTRLEN || salen < sizeof(struct sockaddr_in))
  121. return 0;
  122. memset(sap, 0, sizeof(struct sockaddr_in));
  123. if (in4_pton(buf, buflen, addr, '\0', NULL) == 0)
  124. return 0;
  125. sin->sin_family = AF_INET;
  126. return sizeof(struct sockaddr_in);;
  127. }
  128. #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  129. static int rpc_parse_scope_id(const char *buf, const size_t buflen,
  130. const char *delim, struct sockaddr_in6 *sin6)
  131. {
  132. char *p;
  133. size_t len;
  134. if ((buf + buflen) == delim)
  135. return 1;
  136. if (*delim != IPV6_SCOPE_DELIMITER)
  137. return 0;
  138. if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
  139. !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
  140. return 0;
  141. len = (buf + buflen) - delim - 1;
  142. p = kstrndup(delim + 1, len, GFP_KERNEL);
  143. if (p) {
  144. unsigned long scope_id = 0;
  145. struct net_device *dev;
  146. dev = dev_get_by_name(&init_net, p);
  147. if (dev != NULL) {
  148. scope_id = dev->ifindex;
  149. dev_put(dev);
  150. } else {
  151. if (strict_strtoul(p, 10, &scope_id) == 0) {
  152. kfree(p);
  153. return 0;
  154. }
  155. }
  156. kfree(p);
  157. sin6->sin6_scope_id = scope_id;
  158. return 1;
  159. }
  160. return 0;
  161. }
  162. static size_t rpc_pton6(const char *buf, const size_t buflen,
  163. struct sockaddr *sap, const size_t salen)
  164. {
  165. struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  166. u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
  167. const char *delim;
  168. if (buflen > (INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN) ||
  169. salen < sizeof(struct sockaddr_in6))
  170. return 0;
  171. memset(sap, 0, sizeof(struct sockaddr_in6));
  172. if (in6_pton(buf, buflen, addr, IPV6_SCOPE_DELIMITER, &delim) == 0)
  173. return 0;
  174. if (!rpc_parse_scope_id(buf, buflen, delim, sin6))
  175. return 0;
  176. sin6->sin6_family = AF_INET6;
  177. return sizeof(struct sockaddr_in6);
  178. }
  179. #else
  180. static size_t rpc_pton6(const char *buf, const size_t buflen,
  181. struct sockaddr *sap, const size_t salen)
  182. {
  183. return 0;
  184. }
  185. #endif
  186. /**
  187. * rpc_pton - Construct a sockaddr in @sap
  188. * @buf: C string containing presentation format IP address
  189. * @buflen: length of presentation address in bytes
  190. * @sap: buffer into which to plant socket address
  191. * @salen: size of buffer in bytes
  192. *
  193. * Returns the size of the socket address if successful; otherwise
  194. * zero is returned.
  195. *
  196. * Plants a socket address in @sap and returns the size of the
  197. * socket address, if successful. Returns zero if an error
  198. * occurred.
  199. */
  200. size_t rpc_pton(const char *buf, const size_t buflen,
  201. struct sockaddr *sap, const size_t salen)
  202. {
  203. unsigned int i;
  204. for (i = 0; i < buflen; i++)
  205. if (buf[i] == ':')
  206. return rpc_pton6(buf, buflen, sap, salen);
  207. return rpc_pton4(buf, buflen, sap, salen);
  208. }
  209. EXPORT_SYMBOL_GPL(rpc_pton);
  210. /**
  211. * rpc_sockaddr2uaddr - Construct a universal address string from @sap.
  212. * @sap: socket address
  213. *
  214. * Returns a %NUL-terminated string in dynamically allocated memory;
  215. * otherwise NULL is returned if an error occurred. Caller must
  216. * free the returned string.
  217. */
  218. char *rpc_sockaddr2uaddr(const struct sockaddr *sap)
  219. {
  220. char portbuf[RPCBIND_MAXUADDRPLEN];
  221. char addrbuf[RPCBIND_MAXUADDRLEN];
  222. unsigned short port;
  223. switch (sap->sa_family) {
  224. case AF_INET:
  225. if (rpc_ntop4(sap, addrbuf, sizeof(addrbuf)) == 0)
  226. return NULL;
  227. port = ntohs(((struct sockaddr_in *)sap)->sin_port);
  228. break;
  229. case AF_INET6:
  230. if (rpc_ntop6_noscopeid(sap, addrbuf, sizeof(addrbuf)) == 0)
  231. return NULL;
  232. port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
  233. break;
  234. default:
  235. return NULL;
  236. }
  237. if (snprintf(portbuf, sizeof(portbuf),
  238. ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf))
  239. return NULL;
  240. if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
  241. return NULL;
  242. return kstrdup(addrbuf, GFP_KERNEL);
  243. }
  244. EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
  245. /**
  246. * rpc_uaddr2sockaddr - convert a universal address to a socket address.
  247. * @uaddr: C string containing universal address to convert
  248. * @uaddr_len: length of universal address string
  249. * @sap: buffer into which to plant socket address
  250. * @salen: size of buffer
  251. *
  252. * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and
  253. * rpc_pton() require proper string termination to be successful.
  254. *
  255. * Returns the size of the socket address if successful; otherwise
  256. * zero is returned.
  257. */
  258. size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
  259. struct sockaddr *sap, const size_t salen)
  260. {
  261. char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')];
  262. unsigned long portlo, porthi;
  263. unsigned short port;
  264. if (uaddr_len > RPCBIND_MAXUADDRLEN)
  265. return 0;
  266. memcpy(buf, uaddr, uaddr_len);
  267. buf[uaddr_len] = '\0';
  268. c = strrchr(buf, '.');
  269. if (unlikely(c == NULL))
  270. return 0;
  271. if (unlikely(strict_strtoul(c + 1, 10, &portlo) != 0))
  272. return 0;
  273. if (unlikely(portlo > 255))
  274. return 0;
  275. *c = '\0';
  276. c = strrchr(buf, '.');
  277. if (unlikely(c == NULL))
  278. return 0;
  279. if (unlikely(strict_strtoul(c + 1, 10, &porthi) != 0))
  280. return 0;
  281. if (unlikely(porthi > 255))
  282. return 0;
  283. port = (unsigned short)((porthi << 8) | portlo);
  284. *c = '\0';
  285. if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
  286. return 0;
  287. switch (sap->sa_family) {
  288. case AF_INET:
  289. ((struct sockaddr_in *)sap)->sin_port = htons(port);
  290. return sizeof(struct sockaddr_in);
  291. case AF_INET6:
  292. ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
  293. return sizeof(struct sockaddr_in6);
  294. }
  295. return 0;
  296. }
  297. EXPORT_SYMBOL_GPL(rpc_uaddr2sockaddr);