15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/ossocket.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <stdio.h>
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h>
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <limits.h>
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int inet_aton(const char *cp, struct in_addr *inp) {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned int p1 = 0, p2 = 0, p3 = 0, p4 = 0;
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int consumed = 0;
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int matched = sscanf(cp, "%u.%u.%u.%u%n", &p1, &p2, &p3, &p4,
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       &consumed);
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (strlen(cp) == consumed && matched == 4) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((p1 | p2 | p3 | p4) <= UCHAR_MAX) {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      in_addr_t host_order_addr = (p1 << 24) | (p2 << 16) | (p3 << 8) | p4;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      inp->s_addr = htonl(host_order_addr);
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return 1;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  matched = sscanf(cp, "%u.%u.%u%n", &p1, &p2, &p3, &consumed);
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (strlen(cp) == consumed && matched == 3) {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((p1 | p2) <= UCHAR_MAX && p3 <= USHRT_MAX) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      in_addr_t host_order_addr = (p1 << 24) | (p2 << 16) | p3;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      inp->s_addr = htonl(host_order_addr);
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return 1;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  matched = sscanf(cp, "%u.%u%n", &p1, &p2, &consumed);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (strlen(cp) == consumed && matched == 2) {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (p1 <= UCHAR_MAX && p1 <= 1 << 24) {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      in_addr_t host_order_addr = (p1 << 24) | p2;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      inp->s_addr = htonl(host_order_addr);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return 1;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  matched = sscanf(cp, "%u%n", &p1, &consumed);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (strlen(cp) == consumed && matched == 1) {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    inp->s_addr = htonl(p1);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 1;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Failure
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 0;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
56