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 */
net_ratelimit(void)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
in_aton(const char * str)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
xdigit2bin(char c,int delim)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 */
in4_pton(const char * src,int srclen,u8 * dst,int delim,const char ** end)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 */
in6_pton(const char * src,int srclen,u8 * dst,int delim,const char ** end)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
inet4_pton(const char * src,u16 port_num,struct sockaddr_storage * addr)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
inet6_pton(struct net * net,const char * src,u16 port_num,struct sockaddr_storage * addr)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 */
inet_pton_with_scope(struct net * net,__kernel_sa_family_t af,const char * src,const char * port,struct sockaddr_storage * addr)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
inet_addr_is_any(struct sockaddr_storage * addr)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
inet_proto_csum_replace4(__sum16 * sum,struct sk_buff * skb,__be32 from,__be32 to,bool pseudohdr)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 */
inet_proto_csum_replace16(__sum16 * sum,struct sk_buff * skb,const __be32 * from,const __be32 * to,bool pseudohdr)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
inet_proto_csum_replace_by_diff(__sum16 * sum,struct sk_buff * skb,__wsum diff,bool pseudohdr,bool ipv6)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