uboot/lib/net_utils.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Generic network code. Moved from net.c
   4 *
   5 * Copyright 1994 - 2000 Neil Russell.
   6 * Copyright 2000 Roland Borde
   7 * Copyright 2000 Paolo Scaffardi
   8 * Copyright 2000-2002 Wolfgang Denk, wd@denx.de
   9 * Copyright 2009 Dirk Behme, dirk.behme@googlemail.com
  10 */
  11
  12#include <common.h>
  13#include <net.h>
  14
  15struct in_addr string_to_ip(const char *s)
  16{
  17        struct in_addr addr;
  18        char *e;
  19        int i;
  20
  21        addr.s_addr = 0;
  22        if (s == NULL)
  23                return addr;
  24
  25        for (addr.s_addr = 0, i = 0; i < 4; ++i) {
  26                ulong val = s ? dectoul(s, &e) : 0;
  27                if (val > 255) {
  28                        addr.s_addr = 0;
  29                        return addr;
  30                }
  31                if (i != 3 && *e != '.') {
  32                        addr.s_addr = 0;
  33                        return addr;
  34                }
  35                addr.s_addr <<= 8;
  36                addr.s_addr |= (val & 0xFF);
  37                if (s) {
  38                        s = (*e) ? e+1 : e;
  39                }
  40        }
  41
  42        addr.s_addr = htonl(addr.s_addr);
  43        return addr;
  44}
  45
  46void string_to_enetaddr(const char *addr, uint8_t *enetaddr)
  47{
  48        char *end;
  49        int i;
  50
  51        if (!enetaddr)
  52                return;
  53
  54        for (i = 0; i < 6; ++i) {
  55                enetaddr[i] = addr ? hextoul(addr, &end) : 0;
  56                if (addr)
  57                        addr = (*end) ? end + 1 : end;
  58        }
  59}
  60
  61uint compute_ip_checksum(const void *vptr, uint nbytes)
  62{
  63        int sum, oddbyte;
  64        const unsigned short *ptr = vptr;
  65
  66        sum = 0;
  67        while (nbytes > 1) {
  68                sum += *ptr++;
  69                nbytes -= 2;
  70        }
  71        if (nbytes == 1) {
  72                oddbyte = 0;
  73                ((u8 *)&oddbyte)[0] = *(u8 *)ptr;
  74                ((u8 *)&oddbyte)[1] = 0;
  75                sum += oddbyte;
  76        }
  77        sum = (sum >> 16) + (sum & 0xffff);
  78        sum += (sum >> 16);
  79        sum = ~sum & 0xffff;
  80
  81        return sum;
  82}
  83
  84uint add_ip_checksums(uint offset, uint sum, uint new)
  85{
  86        ulong checksum;
  87
  88        sum = ~sum & 0xffff;
  89        new = ~new & 0xffff;
  90        if (offset & 1) {
  91                /*
  92                 * byte-swap the sum if it came from an odd offset; since the
  93                 * computation is endian-independent this works.
  94                 */
  95                new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
  96        }
  97        checksum = sum + new;
  98        if (checksum > 0xffff)
  99                checksum -= 0xffff;
 100
 101        return (~checksum) & 0xffff;
 102}
 103
 104int ip_checksum_ok(const void *addr, uint nbytes)
 105{
 106        return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
 107}
 108