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