addr.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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. * To keep the result as short as possible, especially
  53. * since we don't shorthand, we don't want leading zeros
  54. * in each halfword, so avoid %pI6.
  55. */
  56. return snprintf(buf, buflen, "%x:%x:%x:%x:%x:%x:%x:%x",
  57. ntohs(addr->s6_addr16[0]), ntohs(addr->s6_addr16[1]),
  58. ntohs(addr->s6_addr16[2]), ntohs(addr->s6_addr16[3]),
  59. ntohs(addr->s6_addr16[4]), ntohs(addr->s6_addr16[5]),
  60. ntohs(addr->s6_addr16[6]), ntohs(addr->s6_addr16[7]));
  61. }
  62. static size_t rpc_ntop6(const struct sockaddr *sap,
  63. char *buf, const size_t buflen)
  64. {
  65. const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  66. char scopebuf[IPV6_SCOPE_ID_LEN];
  67. size_t len;
  68. int rc;
  69. len = rpc_ntop6_noscopeid(sap, buf, buflen);
  70. if (unlikely(len == 0))
  71. return len;
  72. if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
  73. !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
  74. return len;
  75. rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u",
  76. IPV6_SCOPE_DELIMITER, sin6->sin6_scope_id);
  77. if (unlikely((size_t)rc > sizeof(scopebuf)))
  78. return 0;
  79. len += rc;
  80. if (unlikely(len > buflen))
  81. return 0;
  82. strcat(buf, scopebuf);
  83. return len;
  84. }
  85. #else /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
  86. static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
  87. char *buf, const int buflen)
  88. {
  89. return 0;
  90. }
  91. static size_t rpc_ntop6(const struct sockaddr *sap,
  92. char *buf, const size_t buflen)
  93. {
  94. return 0;
  95. }
  96. #endif /* !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) */
  97. static int rpc_ntop4(const struct sockaddr *sap,
  98. char *buf, const size_t buflen)
  99. {
  100. const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
  101. return snprintf(buf, buflen, "%pI4", &sin->sin_addr);
  102. }
  103. /**
  104. * rpc_ntop - construct a presentation address in @buf
  105. * @sap: socket address
  106. * @buf: construction area
  107. * @buflen: size of @buf, in bytes
  108. *
  109. * Plants a %NUL-terminated string in @buf and returns the length
  110. * of the string, excluding the %NUL. Otherwise zero is returned.
  111. */
  112. size_t rpc_ntop(const struct sockaddr *sap, char *buf, const size_t buflen)
  113. {
  114. switch (sap->sa_family) {
  115. case AF_INET:
  116. return rpc_ntop4(sap, buf, buflen);
  117. case AF_INET6:
  118. return rpc_ntop6(sap, buf, buflen);
  119. }
  120. return 0;
  121. }
  122. EXPORT_SYMBOL_GPL(rpc_ntop);
  123. static size_t rpc_pton4(const char *buf, const size_t buflen,
  124. struct sockaddr *sap, const size_t salen)
  125. {
  126. struct sockaddr_in *sin = (struct sockaddr_in *)sap;
  127. u8 *addr = (u8 *)&sin->sin_addr.s_addr;
  128. if (buflen > INET_ADDRSTRLEN || salen < sizeof(struct sockaddr_in))
  129. return 0;
  130. memset(sap, 0, sizeof(struct sockaddr_in));
  131. if (in4_pton(buf, buflen, addr, '\0', NULL) == 0)
  132. return 0;
  133. sin->sin_family = AF_INET;
  134. return sizeof(struct sockaddr_in);;
  135. }
  136. #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  137. static int rpc_parse_scope_id(const char *buf, const size_t buflen,
  138. const char *delim, struct sockaddr_in6 *sin6)
  139. {
  140. char *p;
  141. size_t len;
  142. if ((buf + buflen) == delim)
  143. return 1;
  144. if (*delim != IPV6_SCOPE_DELIMITER)
  145. return 0;
  146. if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
  147. !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL))
  148. return 0;
  149. len = (buf + buflen) - delim - 1;
  150. p = kstrndup(delim + 1, len, GFP_KERNEL);
  151. if (p) {
  152. unsigned long scope_id = 0;
  153. struct net_device *dev;
  154. dev = dev_get_by_name(&init_net, p);
  155. if (dev != NULL) {
  156. scope_id = dev->ifindex;
  157. dev_put(dev);
  158. } else {
  159. if (strict_strtoul(p, 10, &scope_id) == 0) {
  160. kfree(p);
  161. return 0;
  162. }
  163. }
  164. kfree(p);
  165. sin6->sin6_scope_id = scope_id;
  166. return 1;
  167. }
  168. return 0;
  169. }
  170. static size_t rpc_pton6(const char *buf, const size_t buflen,
  171. struct sockaddr *sap, const size_t salen)
  172. {
  173. struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
  174. u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
  175. const char *delim;
  176. if (buflen > (INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN) ||
  177. salen < sizeof(struct sockaddr_in6))
  178. return 0;
  179. memset(sap, 0, sizeof(struct sockaddr_in6));
  180. if (in6_pton(buf, buflen, addr, IPV6_SCOPE_DELIMITER, &delim) == 0)
  181. return 0;
  182. if (!rpc_parse_scope_id(buf, buflen, delim, sin6))
  183. return 0;
  184. sin6->sin6_family = AF_INET6;
  185. return sizeof(struct sockaddr_in6);
  186. }
  187. #else
  188. static size_t rpc_pton6(const char *buf, const size_t buflen,
  189. struct sockaddr *sap, const size_t salen)
  190. {
  191. return 0;
  192. }
  193. #endif
  194. /**
  195. * rpc_pton - Construct a sockaddr in @sap
  196. * @buf: C string containing presentation format IP address
  197. * @buflen: length of presentation address in bytes
  198. * @sap: buffer into which to plant socket address
  199. * @salen: size of buffer in bytes
  200. *
  201. * Returns the size of the socket address if successful; otherwise
  202. * zero is returned.
  203. *
  204. * Plants a socket address in @sap and returns the size of the
  205. * socket address, if successful. Returns zero if an error
  206. * occurred.
  207. */
  208. size_t rpc_pton(const char *buf, const size_t buflen,
  209. struct sockaddr *sap, const size_t salen)
  210. {
  211. unsigned int i;
  212. for (i = 0; i < buflen; i++)
  213. if (buf[i] == ':')
  214. return rpc_pton6(buf, buflen, sap, salen);
  215. return rpc_pton4(buf, buflen, sap, salen);
  216. }
  217. EXPORT_SYMBOL_GPL(rpc_pton);
  218. /**
  219. * rpc_sockaddr2uaddr - Construct a universal address string from @sap.
  220. * @sap: socket address
  221. *
  222. * Returns a %NUL-terminated string in dynamically allocated memory;
  223. * otherwise NULL is returned if an error occurred. Caller must
  224. * free the returned string.
  225. */
  226. char *rpc_sockaddr2uaddr(const struct sockaddr *sap)
  227. {
  228. char portbuf[RPCBIND_MAXUADDRPLEN];
  229. char addrbuf[RPCBIND_MAXUADDRLEN];
  230. unsigned short port;
  231. switch (sap->sa_family) {
  232. case AF_INET:
  233. if (rpc_ntop4(sap, addrbuf, sizeof(addrbuf)) == 0)
  234. return NULL;
  235. port = ntohs(((struct sockaddr_in *)sap)->sin_port);
  236. break;
  237. case AF_INET6:
  238. if (rpc_ntop6_noscopeid(sap, addrbuf, sizeof(addrbuf)) == 0)
  239. return NULL;
  240. port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
  241. break;
  242. default:
  243. return NULL;
  244. }
  245. if (snprintf(portbuf, sizeof(portbuf),
  246. ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf))
  247. return NULL;
  248. if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
  249. return NULL;
  250. return kstrdup(addrbuf, GFP_KERNEL);
  251. }
  252. EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
  253. /**
  254. * rpc_uaddr2sockaddr - convert a universal address to a socket address.
  255. * @uaddr: C string containing universal address to convert
  256. * @uaddr_len: length of universal address string
  257. * @sap: buffer into which to plant socket address
  258. * @salen: size of buffer
  259. *
  260. * Returns the size of the socket address if successful; otherwise
  261. * zero is returned.
  262. */
  263. size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
  264. struct sockaddr *sap, const size_t salen)
  265. {
  266. char *c, buf[RPCBIND_MAXUADDRLEN];
  267. unsigned long portlo, porthi;
  268. unsigned short port;
  269. if (uaddr_len > sizeof(buf))
  270. return 0;
  271. memcpy(buf, uaddr, uaddr_len);
  272. buf[uaddr_len] = '\n';
  273. buf[uaddr_len + 1] = '\0';
  274. c = strrchr(buf, '.');
  275. if (unlikely(c == NULL))
  276. return 0;
  277. if (unlikely(strict_strtoul(c + 1, 10, &portlo) != 0))
  278. return 0;
  279. if (unlikely(portlo > 255))
  280. return 0;
  281. c[0] = '\n';
  282. c[1] = '\0';
  283. c = strrchr(buf, '.');
  284. if (unlikely(c == NULL))
  285. return 0;
  286. if (unlikely(strict_strtoul(c + 1, 10, &porthi) != 0))
  287. return 0;
  288. if (unlikely(porthi > 255))
  289. return 0;
  290. port = (unsigned short)((porthi << 8) | portlo);
  291. c[0] = '\0';
  292. if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
  293. return 0;
  294. switch (sap->sa_family) {
  295. case AF_INET:
  296. ((struct sockaddr_in *)sap)->sin_port = htons(port);
  297. return sizeof(struct sockaddr_in);
  298. case AF_INET6:
  299. ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
  300. return sizeof(struct sockaddr_in6);
  301. }
  302. return 0;
  303. }
  304. EXPORT_SYMBOL_GPL(rpc_uaddr2sockaddr);