1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Generic address resultion entity
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Authors:
6*4882a593Smuzhiyun * net_random Alan Cox
7*4882a593Smuzhiyun * net_ratelimit Andi Kleen
8*4882a593Smuzhiyun * in{4,6}_pton YOSHIFUJI Hideaki, Copyright (C)2006 USAGI/WIDE Project
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Created by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/jiffies.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/ctype.h>
17*4882a593Smuzhiyun #include <linux/inet.h>
18*4882a593Smuzhiyun #include <linux/mm.h>
19*4882a593Smuzhiyun #include <linux/net.h>
20*4882a593Smuzhiyun #include <linux/string.h>
21*4882a593Smuzhiyun #include <linux/types.h>
22*4882a593Smuzhiyun #include <linux/percpu.h>
23*4882a593Smuzhiyun #include <linux/init.h>
24*4882a593Smuzhiyun #include <linux/ratelimit.h>
25*4882a593Smuzhiyun #include <linux/socket.h>
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #include <net/sock.h>
28*4882a593Smuzhiyun #include <net/net_ratelimit.h>
29*4882a593Smuzhiyun #include <net/ipv6.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <asm/byteorder.h>
32*4882a593Smuzhiyun #include <linux/uaccess.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun DEFINE_RATELIMIT_STATE(net_ratelimit_state, 5 * HZ, 10);
35*4882a593Smuzhiyun /*
36*4882a593Smuzhiyun * All net warning printk()s should be guarded by this function.
37*4882a593Smuzhiyun */
net_ratelimit(void)38*4882a593Smuzhiyun int net_ratelimit(void)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun return __ratelimit(&net_ratelimit_state);
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun EXPORT_SYMBOL(net_ratelimit);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun * Convert an ASCII string to binary IP.
46*4882a593Smuzhiyun * This is outside of net/ipv4/ because various code that uses IP addresses
47*4882a593Smuzhiyun * is otherwise not dependent on the TCP/IP stack.
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun
in_aton(const char * str)50*4882a593Smuzhiyun __be32 in_aton(const char *str)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun unsigned int l;
53*4882a593Smuzhiyun unsigned int val;
54*4882a593Smuzhiyun int i;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun l = 0;
57*4882a593Smuzhiyun for (i = 0; i < 4; i++) {
58*4882a593Smuzhiyun l <<= 8;
59*4882a593Smuzhiyun if (*str != '\0') {
60*4882a593Smuzhiyun val = 0;
61*4882a593Smuzhiyun while (*str != '\0' && *str != '.' && *str != '\n') {
62*4882a593Smuzhiyun val *= 10;
63*4882a593Smuzhiyun val += *str - '0';
64*4882a593Smuzhiyun str++;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun l |= val;
67*4882a593Smuzhiyun if (*str != '\0')
68*4882a593Smuzhiyun str++;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun return htonl(l);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun EXPORT_SYMBOL(in_aton);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #define IN6PTON_XDIGIT 0x00010000
76*4882a593Smuzhiyun #define IN6PTON_DIGIT 0x00020000
77*4882a593Smuzhiyun #define IN6PTON_COLON_MASK 0x00700000
78*4882a593Smuzhiyun #define IN6PTON_COLON_1 0x00100000 /* single : requested */
79*4882a593Smuzhiyun #define IN6PTON_COLON_2 0x00200000 /* second : requested */
80*4882a593Smuzhiyun #define IN6PTON_COLON_1_2 0x00400000 /* :: requested */
81*4882a593Smuzhiyun #define IN6PTON_DOT 0x00800000 /* . */
82*4882a593Smuzhiyun #define IN6PTON_DELIM 0x10000000
83*4882a593Smuzhiyun #define IN6PTON_NULL 0x20000000 /* first/tail */
84*4882a593Smuzhiyun #define IN6PTON_UNKNOWN 0x40000000
85*4882a593Smuzhiyun
xdigit2bin(char c,int delim)86*4882a593Smuzhiyun static inline int xdigit2bin(char c, int delim)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun int val;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun if (c == delim || c == '\0')
91*4882a593Smuzhiyun return IN6PTON_DELIM;
92*4882a593Smuzhiyun if (c == ':')
93*4882a593Smuzhiyun return IN6PTON_COLON_MASK;
94*4882a593Smuzhiyun if (c == '.')
95*4882a593Smuzhiyun return IN6PTON_DOT;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun val = hex_to_bin(c);
98*4882a593Smuzhiyun if (val >= 0)
99*4882a593Smuzhiyun return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun if (delim == -1)
102*4882a593Smuzhiyun return IN6PTON_DELIM;
103*4882a593Smuzhiyun return IN6PTON_UNKNOWN;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * in4_pton - convert an IPv4 address from literal to binary representation
108*4882a593Smuzhiyun * @src: the start of the IPv4 address string
109*4882a593Smuzhiyun * @srclen: the length of the string, -1 means strlen(src)
110*4882a593Smuzhiyun * @dst: the binary (u8[4] array) representation of the IPv4 address
111*4882a593Smuzhiyun * @delim: the delimiter of the IPv4 address in @src, -1 means no delimiter
112*4882a593Smuzhiyun * @end: A pointer to the end of the parsed string will be placed here
113*4882a593Smuzhiyun *
114*4882a593Smuzhiyun * Return one on success, return zero when any error occurs
115*4882a593Smuzhiyun * and @end will point to the end of the parsed string.
116*4882a593Smuzhiyun *
117*4882a593Smuzhiyun */
in4_pton(const char * src,int srclen,u8 * dst,int delim,const char ** end)118*4882a593Smuzhiyun int in4_pton(const char *src, int srclen,
119*4882a593Smuzhiyun u8 *dst,
120*4882a593Smuzhiyun int delim, const char **end)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun const char *s;
123*4882a593Smuzhiyun u8 *d;
124*4882a593Smuzhiyun u8 dbuf[4];
125*4882a593Smuzhiyun int ret = 0;
126*4882a593Smuzhiyun int i;
127*4882a593Smuzhiyun int w = 0;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun if (srclen < 0)
130*4882a593Smuzhiyun srclen = strlen(src);
131*4882a593Smuzhiyun s = src;
132*4882a593Smuzhiyun d = dbuf;
133*4882a593Smuzhiyun i = 0;
134*4882a593Smuzhiyun while (1) {
135*4882a593Smuzhiyun int c;
136*4882a593Smuzhiyun c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
137*4882a593Smuzhiyun if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) {
138*4882a593Smuzhiyun goto out;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
141*4882a593Smuzhiyun if (w == 0)
142*4882a593Smuzhiyun goto out;
143*4882a593Smuzhiyun *d++ = w & 0xff;
144*4882a593Smuzhiyun w = 0;
145*4882a593Smuzhiyun i++;
146*4882a593Smuzhiyun if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
147*4882a593Smuzhiyun if (i != 4)
148*4882a593Smuzhiyun goto out;
149*4882a593Smuzhiyun break;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun goto cont;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun w = (w * 10) + c;
154*4882a593Smuzhiyun if ((w & 0xffff) > 255) {
155*4882a593Smuzhiyun goto out;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun cont:
158*4882a593Smuzhiyun if (i >= 4)
159*4882a593Smuzhiyun goto out;
160*4882a593Smuzhiyun s++;
161*4882a593Smuzhiyun srclen--;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun ret = 1;
164*4882a593Smuzhiyun memcpy(dst, dbuf, sizeof(dbuf));
165*4882a593Smuzhiyun out:
166*4882a593Smuzhiyun if (end)
167*4882a593Smuzhiyun *end = s;
168*4882a593Smuzhiyun return ret;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun EXPORT_SYMBOL(in4_pton);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /**
173*4882a593Smuzhiyun * in6_pton - convert an IPv6 address from literal to binary representation
174*4882a593Smuzhiyun * @src: the start of the IPv6 address string
175*4882a593Smuzhiyun * @srclen: the length of the string, -1 means strlen(src)
176*4882a593Smuzhiyun * @dst: the binary (u8[16] array) representation of the IPv6 address
177*4882a593Smuzhiyun * @delim: the delimiter of the IPv6 address in @src, -1 means no delimiter
178*4882a593Smuzhiyun * @end: A pointer to the end of the parsed string will be placed here
179*4882a593Smuzhiyun *
180*4882a593Smuzhiyun * Return one on success, return zero when any error occurs
181*4882a593Smuzhiyun * and @end will point to the end of the parsed string.
182*4882a593Smuzhiyun *
183*4882a593Smuzhiyun */
in6_pton(const char * src,int srclen,u8 * dst,int delim,const char ** end)184*4882a593Smuzhiyun int in6_pton(const char *src, int srclen,
185*4882a593Smuzhiyun u8 *dst,
186*4882a593Smuzhiyun int delim, const char **end)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun const char *s, *tok = NULL;
189*4882a593Smuzhiyun u8 *d, *dc = NULL;
190*4882a593Smuzhiyun u8 dbuf[16];
191*4882a593Smuzhiyun int ret = 0;
192*4882a593Smuzhiyun int i;
193*4882a593Smuzhiyun int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
194*4882a593Smuzhiyun int w = 0;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun memset(dbuf, 0, sizeof(dbuf));
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun s = src;
199*4882a593Smuzhiyun d = dbuf;
200*4882a593Smuzhiyun if (srclen < 0)
201*4882a593Smuzhiyun srclen = strlen(src);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun while (1) {
204*4882a593Smuzhiyun int c;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
207*4882a593Smuzhiyun if (!(c & state))
208*4882a593Smuzhiyun goto out;
209*4882a593Smuzhiyun if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
210*4882a593Smuzhiyun /* process one 16-bit word */
211*4882a593Smuzhiyun if (!(state & IN6PTON_NULL)) {
212*4882a593Smuzhiyun *d++ = (w >> 8) & 0xff;
213*4882a593Smuzhiyun *d++ = w & 0xff;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun w = 0;
216*4882a593Smuzhiyun if (c & IN6PTON_DELIM) {
217*4882a593Smuzhiyun /* We've processed last word */
218*4882a593Smuzhiyun break;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun /*
221*4882a593Smuzhiyun * COLON_1 => XDIGIT
222*4882a593Smuzhiyun * COLON_2 => XDIGIT|DELIM
223*4882a593Smuzhiyun * COLON_1_2 => COLON_2
224*4882a593Smuzhiyun */
225*4882a593Smuzhiyun switch (state & IN6PTON_COLON_MASK) {
226*4882a593Smuzhiyun case IN6PTON_COLON_2:
227*4882a593Smuzhiyun dc = d;
228*4882a593Smuzhiyun state = IN6PTON_XDIGIT | IN6PTON_DELIM;
229*4882a593Smuzhiyun if (dc - dbuf >= sizeof(dbuf))
230*4882a593Smuzhiyun state |= IN6PTON_NULL;
231*4882a593Smuzhiyun break;
232*4882a593Smuzhiyun case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
233*4882a593Smuzhiyun state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
234*4882a593Smuzhiyun break;
235*4882a593Smuzhiyun case IN6PTON_COLON_1:
236*4882a593Smuzhiyun state = IN6PTON_XDIGIT;
237*4882a593Smuzhiyun break;
238*4882a593Smuzhiyun case IN6PTON_COLON_1_2:
239*4882a593Smuzhiyun state = IN6PTON_COLON_2;
240*4882a593Smuzhiyun break;
241*4882a593Smuzhiyun default:
242*4882a593Smuzhiyun state = 0;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun tok = s + 1;
245*4882a593Smuzhiyun goto cont;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun if (c & IN6PTON_DOT) {
249*4882a593Smuzhiyun ret = in4_pton(tok ? tok : s, srclen + (int)(s - tok), d, delim, &s);
250*4882a593Smuzhiyun if (ret > 0) {
251*4882a593Smuzhiyun d += 4;
252*4882a593Smuzhiyun break;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun goto out;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun w = (w << 4) | (0xff & c);
258*4882a593Smuzhiyun state = IN6PTON_COLON_1 | IN6PTON_DELIM;
259*4882a593Smuzhiyun if (!(w & 0xf000)) {
260*4882a593Smuzhiyun state |= IN6PTON_XDIGIT;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
263*4882a593Smuzhiyun state |= IN6PTON_COLON_1_2;
264*4882a593Smuzhiyun state &= ~IN6PTON_DELIM;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun if (d + 2 >= dbuf + sizeof(dbuf)) {
267*4882a593Smuzhiyun state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun cont:
270*4882a593Smuzhiyun if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
271*4882a593Smuzhiyun d + 4 == dbuf + sizeof(dbuf)) {
272*4882a593Smuzhiyun state |= IN6PTON_DOT;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun if (d >= dbuf + sizeof(dbuf)) {
275*4882a593Smuzhiyun state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun s++;
278*4882a593Smuzhiyun srclen--;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun i = 15; d--;
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun if (dc) {
284*4882a593Smuzhiyun while (d >= dc)
285*4882a593Smuzhiyun dst[i--] = *d--;
286*4882a593Smuzhiyun while (i >= dc - dbuf)
287*4882a593Smuzhiyun dst[i--] = 0;
288*4882a593Smuzhiyun while (i >= 0)
289*4882a593Smuzhiyun dst[i--] = *d--;
290*4882a593Smuzhiyun } else
291*4882a593Smuzhiyun memcpy(dst, dbuf, sizeof(dbuf));
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun ret = 1;
294*4882a593Smuzhiyun out:
295*4882a593Smuzhiyun if (end)
296*4882a593Smuzhiyun *end = s;
297*4882a593Smuzhiyun return ret;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun EXPORT_SYMBOL(in6_pton);
300*4882a593Smuzhiyun
inet4_pton(const char * src,u16 port_num,struct sockaddr_storage * addr)301*4882a593Smuzhiyun static int inet4_pton(const char *src, u16 port_num,
302*4882a593Smuzhiyun struct sockaddr_storage *addr)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
305*4882a593Smuzhiyun int srclen = strlen(src);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (srclen > INET_ADDRSTRLEN)
308*4882a593Smuzhiyun return -EINVAL;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun if (in4_pton(src, srclen, (u8 *)&addr4->sin_addr.s_addr,
311*4882a593Smuzhiyun '\n', NULL) == 0)
312*4882a593Smuzhiyun return -EINVAL;
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun addr4->sin_family = AF_INET;
315*4882a593Smuzhiyun addr4->sin_port = htons(port_num);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun return 0;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
inet6_pton(struct net * net,const char * src,u16 port_num,struct sockaddr_storage * addr)320*4882a593Smuzhiyun static int inet6_pton(struct net *net, const char *src, u16 port_num,
321*4882a593Smuzhiyun struct sockaddr_storage *addr)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
324*4882a593Smuzhiyun const char *scope_delim;
325*4882a593Smuzhiyun int srclen = strlen(src);
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (srclen > INET6_ADDRSTRLEN)
328*4882a593Smuzhiyun return -EINVAL;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (in6_pton(src, srclen, (u8 *)&addr6->sin6_addr.s6_addr,
331*4882a593Smuzhiyun '%', &scope_delim) == 0)
332*4882a593Smuzhiyun return -EINVAL;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun if (ipv6_addr_type(&addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL &&
335*4882a593Smuzhiyun src + srclen != scope_delim && *scope_delim == '%') {
336*4882a593Smuzhiyun struct net_device *dev;
337*4882a593Smuzhiyun char scope_id[16];
338*4882a593Smuzhiyun size_t scope_len = min_t(size_t, sizeof(scope_id) - 1,
339*4882a593Smuzhiyun src + srclen - scope_delim - 1);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun memcpy(scope_id, scope_delim + 1, scope_len);
342*4882a593Smuzhiyun scope_id[scope_len] = '\0';
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun dev = dev_get_by_name(net, scope_id);
345*4882a593Smuzhiyun if (dev) {
346*4882a593Smuzhiyun addr6->sin6_scope_id = dev->ifindex;
347*4882a593Smuzhiyun dev_put(dev);
348*4882a593Smuzhiyun } else if (kstrtouint(scope_id, 0, &addr6->sin6_scope_id)) {
349*4882a593Smuzhiyun return -EINVAL;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun addr6->sin6_family = AF_INET6;
354*4882a593Smuzhiyun addr6->sin6_port = htons(port_num);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun return 0;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun /**
360*4882a593Smuzhiyun * inet_pton_with_scope - convert an IPv4/IPv6 and port to socket address
361*4882a593Smuzhiyun * @net: net namespace (used for scope handling)
362*4882a593Smuzhiyun * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either
363*4882a593Smuzhiyun * @src: the start of the address string
364*4882a593Smuzhiyun * @port: the start of the port string (or NULL for none)
365*4882a593Smuzhiyun * @addr: output socket address
366*4882a593Smuzhiyun *
367*4882a593Smuzhiyun * Return zero on success, return errno when any error occurs.
368*4882a593Smuzhiyun */
inet_pton_with_scope(struct net * net,__kernel_sa_family_t af,const char * src,const char * port,struct sockaddr_storage * addr)369*4882a593Smuzhiyun int inet_pton_with_scope(struct net *net, __kernel_sa_family_t af,
370*4882a593Smuzhiyun const char *src, const char *port, struct sockaddr_storage *addr)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun u16 port_num;
373*4882a593Smuzhiyun int ret = -EINVAL;
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (port) {
376*4882a593Smuzhiyun if (kstrtou16(port, 0, &port_num))
377*4882a593Smuzhiyun return -EINVAL;
378*4882a593Smuzhiyun } else {
379*4882a593Smuzhiyun port_num = 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun switch (af) {
383*4882a593Smuzhiyun case AF_INET:
384*4882a593Smuzhiyun ret = inet4_pton(src, port_num, addr);
385*4882a593Smuzhiyun break;
386*4882a593Smuzhiyun case AF_INET6:
387*4882a593Smuzhiyun ret = inet6_pton(net, src, port_num, addr);
388*4882a593Smuzhiyun break;
389*4882a593Smuzhiyun case AF_UNSPEC:
390*4882a593Smuzhiyun ret = inet4_pton(src, port_num, addr);
391*4882a593Smuzhiyun if (ret)
392*4882a593Smuzhiyun ret = inet6_pton(net, src, port_num, addr);
393*4882a593Smuzhiyun break;
394*4882a593Smuzhiyun default:
395*4882a593Smuzhiyun pr_err("unexpected address family %d\n", af);
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun return ret;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun EXPORT_SYMBOL(inet_pton_with_scope);
401*4882a593Smuzhiyun
inet_addr_is_any(struct sockaddr * addr)402*4882a593Smuzhiyun bool inet_addr_is_any(struct sockaddr *addr)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun if (addr->sa_family == AF_INET6) {
405*4882a593Smuzhiyun struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
406*4882a593Smuzhiyun const struct sockaddr_in6 in6_any =
407*4882a593Smuzhiyun { .sin6_addr = IN6ADDR_ANY_INIT };
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (!memcmp(in6->sin6_addr.s6_addr,
410*4882a593Smuzhiyun in6_any.sin6_addr.s6_addr, 16))
411*4882a593Smuzhiyun return true;
412*4882a593Smuzhiyun } else if (addr->sa_family == AF_INET) {
413*4882a593Smuzhiyun struct sockaddr_in *in = (struct sockaddr_in *)addr;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun if (in->sin_addr.s_addr == htonl(INADDR_ANY))
416*4882a593Smuzhiyun return true;
417*4882a593Smuzhiyun } else {
418*4882a593Smuzhiyun pr_warn("unexpected address family %u\n", addr->sa_family);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun return false;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun EXPORT_SYMBOL(inet_addr_is_any);
424*4882a593Smuzhiyun
inet_proto_csum_replace4(__sum16 * sum,struct sk_buff * skb,__be32 from,__be32 to,bool pseudohdr)425*4882a593Smuzhiyun void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
426*4882a593Smuzhiyun __be32 from, __be32 to, bool pseudohdr)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun if (skb->ip_summed != CHECKSUM_PARTIAL) {
429*4882a593Smuzhiyun csum_replace4(sum, from, to);
430*4882a593Smuzhiyun if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
431*4882a593Smuzhiyun skb->csum = ~csum_add(csum_sub(~(skb->csum),
432*4882a593Smuzhiyun (__force __wsum)from),
433*4882a593Smuzhiyun (__force __wsum)to);
434*4882a593Smuzhiyun } else if (pseudohdr)
435*4882a593Smuzhiyun *sum = ~csum_fold(csum_add(csum_sub(csum_unfold(*sum),
436*4882a593Smuzhiyun (__force __wsum)from),
437*4882a593Smuzhiyun (__force __wsum)to));
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun EXPORT_SYMBOL(inet_proto_csum_replace4);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun /**
442*4882a593Smuzhiyun * inet_proto_csum_replace16 - update layer 4 header checksum field
443*4882a593Smuzhiyun * @sum: Layer 4 header checksum field
444*4882a593Smuzhiyun * @skb: sk_buff for the packet
445*4882a593Smuzhiyun * @from: old IPv6 address
446*4882a593Smuzhiyun * @to: new IPv6 address
447*4882a593Smuzhiyun * @pseudohdr: True if layer 4 header checksum includes pseudoheader
448*4882a593Smuzhiyun *
449*4882a593Smuzhiyun * Update layer 4 header as per the update in IPv6 src/dst address.
450*4882a593Smuzhiyun *
451*4882a593Smuzhiyun * There is no need to update skb->csum in this function, because update in two
452*4882a593Smuzhiyun * fields a.) IPv6 src/dst address and b.) L4 header checksum cancels each other
453*4882a593Smuzhiyun * for skb->csum calculation. Whereas inet_proto_csum_replace4 function needs to
454*4882a593Smuzhiyun * update skb->csum, because update in 3 fields a.) IPv4 src/dst address,
455*4882a593Smuzhiyun * b.) IPv4 Header checksum and c.) L4 header checksum results in same diff as
456*4882a593Smuzhiyun * L4 Header checksum for skb->csum calculation.
457*4882a593Smuzhiyun */
inet_proto_csum_replace16(__sum16 * sum,struct sk_buff * skb,const __be32 * from,const __be32 * to,bool pseudohdr)458*4882a593Smuzhiyun void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
459*4882a593Smuzhiyun const __be32 *from, const __be32 *to,
460*4882a593Smuzhiyun bool pseudohdr)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun __be32 diff[] = {
463*4882a593Smuzhiyun ~from[0], ~from[1], ~from[2], ~from[3],
464*4882a593Smuzhiyun to[0], to[1], to[2], to[3],
465*4882a593Smuzhiyun };
466*4882a593Smuzhiyun if (skb->ip_summed != CHECKSUM_PARTIAL) {
467*4882a593Smuzhiyun *sum = csum_fold(csum_partial(diff, sizeof(diff),
468*4882a593Smuzhiyun ~csum_unfold(*sum)));
469*4882a593Smuzhiyun } else if (pseudohdr)
470*4882a593Smuzhiyun *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
471*4882a593Smuzhiyun csum_unfold(*sum)));
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun EXPORT_SYMBOL(inet_proto_csum_replace16);
474*4882a593Smuzhiyun
inet_proto_csum_replace_by_diff(__sum16 * sum,struct sk_buff * skb,__wsum diff,bool pseudohdr)475*4882a593Smuzhiyun void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb,
476*4882a593Smuzhiyun __wsum diff, bool pseudohdr)
477*4882a593Smuzhiyun {
478*4882a593Smuzhiyun if (skb->ip_summed != CHECKSUM_PARTIAL) {
479*4882a593Smuzhiyun *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum)));
480*4882a593Smuzhiyun if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
481*4882a593Smuzhiyun skb->csum = ~csum_add(diff, ~skb->csum);
482*4882a593Smuzhiyun } else if (pseudohdr) {
483*4882a593Smuzhiyun *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum)));
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun EXPORT_SYMBOL(inet_proto_csum_replace_by_diff);
487