0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _LINUX_SUNRPC_ADDR_H
0009 #define _LINUX_SUNRPC_ADDR_H
0010
0011 #include <linux/socket.h>
0012 #include <linux/in.h>
0013 #include <linux/in6.h>
0014 #include <net/ipv6.h>
0015
0016 size_t rpc_ntop(const struct sockaddr *, char *, const size_t);
0017 size_t rpc_pton(struct net *, const char *, const size_t,
0018 struct sockaddr *, const size_t);
0019 char * rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
0020 size_t rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
0021 struct sockaddr *, const size_t);
0022
0023 static inline unsigned short rpc_get_port(const struct sockaddr *sap)
0024 {
0025 switch (sap->sa_family) {
0026 case AF_INET:
0027 return ntohs(((struct sockaddr_in *)sap)->sin_port);
0028 case AF_INET6:
0029 return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
0030 }
0031 return 0;
0032 }
0033
0034 static inline void rpc_set_port(struct sockaddr *sap,
0035 const unsigned short port)
0036 {
0037 switch (sap->sa_family) {
0038 case AF_INET:
0039 ((struct sockaddr_in *)sap)->sin_port = htons(port);
0040 break;
0041 case AF_INET6:
0042 ((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
0043 break;
0044 }
0045 }
0046
0047 #define IPV6_SCOPE_DELIMITER '%'
0048 #define IPV6_SCOPE_ID_LEN sizeof("%nnnnnnnnnn")
0049
0050 static inline bool rpc_cmp_addr4(const struct sockaddr *sap1,
0051 const struct sockaddr *sap2)
0052 {
0053 const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
0054 const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
0055
0056 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
0057 }
0058
0059 static inline bool __rpc_copy_addr4(struct sockaddr *dst,
0060 const struct sockaddr *src)
0061 {
0062 const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
0063 struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
0064
0065 dsin->sin_family = ssin->sin_family;
0066 dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
0067 return true;
0068 }
0069
0070 #if IS_ENABLED(CONFIG_IPV6)
0071 static inline bool rpc_cmp_addr6(const struct sockaddr *sap1,
0072 const struct sockaddr *sap2)
0073 {
0074 const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
0075 const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
0076
0077 if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
0078 return false;
0079 else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
0080 return sin1->sin6_scope_id == sin2->sin6_scope_id;
0081
0082 return true;
0083 }
0084
0085 static inline bool __rpc_copy_addr6(struct sockaddr *dst,
0086 const struct sockaddr *src)
0087 {
0088 const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
0089 struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;
0090
0091 dsin6->sin6_family = ssin6->sin6_family;
0092 dsin6->sin6_addr = ssin6->sin6_addr;
0093 dsin6->sin6_scope_id = ssin6->sin6_scope_id;
0094 return true;
0095 }
0096 #else
0097 static inline bool rpc_cmp_addr6(const struct sockaddr *sap1,
0098 const struct sockaddr *sap2)
0099 {
0100 return false;
0101 }
0102
0103 static inline bool __rpc_copy_addr6(struct sockaddr *dst,
0104 const struct sockaddr *src)
0105 {
0106 return false;
0107 }
0108 #endif
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
0121 const struct sockaddr *sap2)
0122 {
0123 if (sap1->sa_family == sap2->sa_family) {
0124 switch (sap1->sa_family) {
0125 case AF_INET:
0126 return rpc_cmp_addr4(sap1, sap2);
0127 case AF_INET6:
0128 return rpc_cmp_addr6(sap1, sap2);
0129 }
0130 }
0131 return false;
0132 }
0133
0134
0135
0136
0137
0138
0139 static inline bool rpc_cmp_addr_port(const struct sockaddr *sap1,
0140 const struct sockaddr *sap2)
0141 {
0142 if (!rpc_cmp_addr(sap1, sap2))
0143 return false;
0144 return rpc_get_port(sap1) == rpc_get_port(sap2);
0145 }
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static inline bool rpc_copy_addr(struct sockaddr *dst,
0158 const struct sockaddr *src)
0159 {
0160 switch (src->sa_family) {
0161 case AF_INET:
0162 return __rpc_copy_addr4(dst, src);
0163 case AF_INET6:
0164 return __rpc_copy_addr6(dst, src);
0165 }
0166 return false;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176 static inline u32 rpc_get_scope_id(const struct sockaddr *sa)
0177 {
0178 if (sa->sa_family != AF_INET6)
0179 return 0;
0180
0181 return ((struct sockaddr_in6 *) sa)->sin6_scope_id;
0182 }
0183
0184 #endif