brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.8 KiB · 71419cb Raw
58 lines · cpp
1//===-- Implementation of inet_aton function ------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/arpa/inet/inet_aton.h"10#include "src/__support/common.h"11#include "src/__support/endian_internal.h"12#include "src/__support/str_to_integer.h"13 14namespace LIBC_NAMESPACE_DECL {15 16LLVM_LIBC_FUNCTION(int, inet_aton, (const char *cp, in_addr *inp)) {17  constexpr int IPV4_MAX_DOT_NUM = 3;18  unsigned long parts[IPV4_MAX_DOT_NUM + 1] = {0};19  int dot_num = 0;20 21  for (; dot_num <= IPV4_MAX_DOT_NUM; ++dot_num) {22    auto result = internal::strtointeger<unsigned long>(cp, 0);23    parts[dot_num] = result;24 25    if (result.has_error() || result.parsed_len == 0)26      return 0;27    char next_char = *(cp + result.parsed_len);28    if (next_char != '.' && next_char != '\0')29      return 0;30    else if (next_char == '\0')31      break;32    else33      cp += (result.parsed_len + 1);34  }35 36  if (dot_num > IPV4_MAX_DOT_NUM)37    return 0;38 39  // converts the Internet host address cp from the IPv4 numbers-and-dots40  // notation (a[.b[.c[.d]]]) into binary form (in network byte order)41  unsigned long result = 0;42  for (int i = 0; i <= dot_num; ++i) {43    unsigned long max_part =44        i == dot_num ? (0xffffffffUL >> (8 * dot_num)) : 0xffUL;45    if (parts[i] > max_part)46      return 0;47    int shift = i == dot_num ? 0 : 8 * (IPV4_MAX_DOT_NUM - i);48    result |= parts[i] << shift;49  }50 51  if (inp)52    inp->s_addr = Endian::to_big_endian(static_cast<uint32_t>(result));53 54  return 1;55}56 57} // namespace LIBC_NAMESPACE_DECL58