1/* 2 * Copyright (c) 2000-2001,2003-2004,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// hosts - value-semantics host identifier class 27// 28#include "hosts.h" 29#include <arpa/inet.h> 30#include <netdb.h> 31 32 33namespace Security { 34namespace IPPlusPlus { 35 36 37class NamedHost : public Host::Spec { 38public: 39 NamedHost(const char *name); 40 41 string name() const; 42 set<IPAddress> addresses() const; 43 44 bool operator == (const NamedHost &other) const 45 { return mName == other.mName; } 46 47private: 48 string mName; 49 set<IPAddress> mAddrs; 50}; 51 52 53class IPv4NumberHost : public Host::Spec { 54public: 55 IPv4NumberHost(IPAddress addr) : mAddr(addr) { } 56 57 string name() const; 58 set<IPAddress> addresses() const; 59 60 bool operator == (const IPv4NumberHost &other) const 61 { return mAddr == other.mAddr; } 62 63private: 64 IPAddress mAddr; 65}; 66 67 68// 69// Host basics 70// 71Host::Host(const char *form) 72{ 73 //@@@ IPv4 only at this time 74 IPAddress addr; 75 if (inet_aton(form, &addr)) 76 mSpec = new IPv4NumberHost(addr); 77 else 78 mSpec = new NamedHost(form); 79} 80 81 82// 83// Compare for equality 84// 85bool Host::operator == (const Host &other) const 86{ 87 // really silly hack alert: just compare lexicographically by name 88 return mSpec ? (name() == other.name()) : !other.mSpec; 89} 90 91bool Host::operator < (const Host &other) const 92{ 93 // really silly hack alert: just compare lexicographically by name 94 return !mSpec || (other.mSpec && name() < other.name()); 95} 96 97 98// 99// Compare for subsumption 100// 101bool Host::operator <= (const Host &other) const 102{ 103 return false; 104} 105 106 107// 108// IPv4 address host specs (a single IPv4 address) 109// 110string IPv4NumberHost::name() const 111{ 112 return mAddr; 113} 114 115set<IPAddress> IPv4NumberHost::addresses() const 116{ 117 set<IPAddress> result; 118 result.insert(mAddr); 119 return result; 120} 121 122 123// 124// IPv4 hostname host specs (a set of addresses derived from a name lookup) 125// @@@ If we want to support IPv6, this should ALSO contain IPv6 lookup results. 126// 127NamedHost::NamedHost(const char *name) : mName(name) 128{ 129 //@@@ NOT THREAD SAFE - find another way to do name resolution 130 if (hostent *he = gethostbyname(name)) { 131 for (char **p = he->h_addr_list; *p; p++) 132 mAddrs.insert(*reinterpret_cast<in_addr *>(*p)); 133 secdebug("ipname", "host %s resolves to %ld address(es)", mName.c_str(), mAddrs.size()); 134 return; 135 } 136 UnixError::throwMe(ENOENT); //@@@ h_errno translation or other source 137} 138 139string NamedHost::name() const 140{ 141 return mName; 142} 143 144set<IPAddress> NamedHost::addresses() const 145{ 146 return mAddrs; 147} 148 149 150} // end namespace IPPlusPlus 151} // end namespace Security 152