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