Spinning Topp Logo BlackTopp Studios
inc
ipaddress.cpp
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _networkipaddress_cpp
42 #define _networkipaddress_cpp
43 
44 #include "Network/platformincludes.h.cpp"
45 
46 #include "Network/ipaddress.h"
47 
48 #include "exception.h"
49 #include "serialization.h"
50 
51 #include <cstring>
52 
53 namespace Mezzanine
54 {
55  namespace Network
56  {
59  const UInt16 IPAddress::IPv4StringLength = INET_ADDRSTRLEN;
60  const UInt16 IPAddress::IPv6StringLength = INET6_ADDRSTRLEN;
61 
62  const String IPAddress::IPv4LoopbackAddress = "127.0.0.1";
63  const String IPAddress::IPv4BroadcastAddress = "255.255.255.255";
65 
66  ///////////////////////////////////////////////////////////////////////////////
67  // IPAddress Methods
68 
70  { }
71 
72  IPAddress::IPAddress(const UInt32 Address, const Boole NBO)
73  { this->SetV4Address(Address,NBO); }
74 
75  IPAddress::IPAddress(const String& Address)
76  { this->SetBinaryAddress( IPAddress::Resolve(Address) ); }
77 
79  { this->SetBinaryAddress(Address); }
80 
82  { this->SetBinaryAddress(Other.InternalAddress); }
83 
85  { }
86 
87  ///////////////////////////////////////////////////////////////////////////////
88  // Static Helpers
89 
91  {
92  AddressContainer Ret;
93 
94  in_addr v4Test;
95  memset(&v4Test,0,sizeof(in_addr));
96  #if defined(MEZZ_WINDOWS)
97  if( InetPton( AF_INET, Address.c_str(), &v4Test ) > 0 ) {
98  #elif defined(MEZZ_MACOSX) || defined(MEZZ_LINUX)
99  if( inet_pton( AF_INET, Address.c_str(), &v4Test ) > 0 ) {
100  #endif
101  Ret.resize(IPv4BinaryLength,0);
102  memcpy(&Ret[0],&v4Test.s_addr,IPv4BinaryLength);
103  return Ret;
104  }
105 
106  in6_addr v6Test;
107  memset(&v6Test,0,sizeof(in6_addr));
108  #if defined(MEZZ_WINDOWS)
109  if( InetPton( AF_INET6, Address.c_str(), &v6Test ) > 0 ) {
110  #elif defined(MEZZ_MACOSX) || defined(MEZZ_LINUX)
111  if( inet_pton( AF_INET6, Address.c_str(), &v6Test ) > 0 ) {
112  #endif
113  Ret.resize(IPv6BinaryLength,0);
114  memcpy(&Ret[0],&v6Test.s6_addr[0],IPv6BinaryLength);
115  return Ret;
116  }
117 
118  return Ret;
119  }
120 
122  {
124  switch( Address.size() )
125  {
126  case IPAddress::IPv4BinaryLength: AddressProtocol = Network::NLP_IPv4; break;
127  case IPAddress::IPv6BinaryLength: AddressProtocol = Network::NLP_IPv6; break;
128  case 0:
129  default: AddressProtocol = Network::NLP_Invalid; break;
130  }
131 
132  if( AddressProtocol == Network::NLP_IPv4 ) {
133  char* AddStr = new char[IPv4StringLength];
134  #if defined(MEZZ_WINDOWS)
135  if( InetNtop( AF_INET, const_cast<Int8*>(&Address[0]), AddStr, IPv4StringLength ) != NULL ) {
136  #elif defined(MEZZ_MACOSX) || defined(MEZZ_LINUX)
137  if( inet_ntop( AF_INET, &Address[0], AddStr, IPv4StringLength ) != NULL ) {
138  #endif
139  String Ret(AddStr,strlen(AddStr));
140  delete[] AddStr;
141  return Ret;
142  }
143  }else if( AddressProtocol == Network::NLP_IPv6 ) {
144  char* AddStr = new char[IPv6StringLength];
145  #if defined(MEZZ_WINDOWS)
146  if( InetNtop( AF_INET6, const_cast<Int8*>(&Address[0]), AddStr, IPv6StringLength ) != NULL ) {
147  #elif defined(MEZZ_MACOSX) || defined(MEZZ_LINUX)
148  if( inet_ntop( AF_INET6, &Address[0], AddStr, IPv6StringLength ) != NULL ) {
149  #endif
150  String Ret(AddStr,strlen(AddStr));
151  delete[] AddStr;
152  return Ret;
153  }
154  }
155 
156  return String();
157  }
158 
159  ///////////////////////////////////////////////////////////////////////////////
160  // Utility
161 
163  {
164  switch( this->InternalAddress.size() )
165  {
166  case IPAddress::IPv4BinaryLength: return Network::NLP_IPv4; break;
167  case IPAddress::IPv6BinaryLength: return Network::NLP_IPv6; break;
168  case 0:
169  default: return Network::NLP_Invalid; break;
170  }
171  }
172 
174  { return IPAddress::Resolve(this->InternalAddress); }
175 
177  { this->InternalAddress.assign(Address.begin(),Address.end()); }
178 
180  { return this->InternalAddress; }
181 
182  void IPAddress::SetV4Address(const UInt32 Address, const Boole NBO)
183  {
184  this->InternalAddress.resize(IPAddress::IPv4BinaryLength);
185  *reinterpret_cast<UInt32*>( &this->InternalAddress[0] ) = ( NBO ? Address : htonl(Address) );
186  /*UInt32 Endian = ( NBO ? Address : htonl(Address) );
187  Int8* Converted = reinterpret_cast<Int8*>( &Endian );
188  this->InternalAddress[0] = Converted[0];
189  this->InternalAddress[1] = Converted[1];
190  this->InternalAddress[2] = Converted[2];
191  this->InternalAddress[3] = Converted[3];// */
192  }
193 
195  {
196  if( this->InternalAddress.size() == IPAddress::IPv4BinaryLength ) {
197  UInt32 Ret = *reinterpret_cast<const UInt32*>( &this->InternalAddress[0] );
198  /*UInt32 Ret = 0;
199  std::copy(&this->InternalAddress[0],&this->InternalAddress[4],reinterpret_cast<Int8*>(&Ret));// */
200  if( NBO ) {
201  return Ret;
202  }else{
203  return ntohl(Ret);
204  }
205  }
206  return 0;
207  }
208 
209  ///////////////////////////////////////////////////////////////////////////////
210  // Operators
211 
212  void IPAddress::operator=(const IPAddress& Other)
213  { this->SetBinaryAddress( Other.InternalAddress ); }
214 
216  {
217  if( this->InternalAddress.size() == Other.InternalAddress.size() ) {
218  for( Whole X = 0 ; X < this->InternalAddress.size() ; ++X )
219  {
220  if( this->InternalAddress[X] != Other.InternalAddress[X] ) {
221  return false;
222  }
223  }
224  return true;
225  }
226  return false;
227  }
228 
230  {
231  return !(this->operator==(Other));
232  }
233 
234  ///////////////////////////////////////////////////////////////////////////////
235  // Serialization
236 
237  void IPAddress::ProtoSerialize(XML::Node& ParentNode) const
238  {
239  XML::Node SelfRoot = ParentNode.AppendChild( IPAddress::GetSerializableName() );
240 
241  if( SelfRoot.AppendAttribute("Version").SetValue("1") &&
242  SelfRoot.AppendAttribute("Address").SetValue( this->GetAsString() ) )
243  {
244  return;
245  }else{
246  SerializeError("Create XML Attribute Values",IPAddress::GetSerializableName(),true);
247  }
248  }
249 
251  {
252  XML::Attribute CurrAttrib;
253 
254  if( !SelfRoot.Empty() && SelfRoot.Name() == IPAddress::GetSerializableName() ) {
255  if( SelfRoot.GetAttribute("Version").AsInt() == 1 ) {
256  CurrAttrib = SelfRoot.GetAttribute("Address");
257  if( !CurrAttrib.Empty() )
258  this->SetBinaryAddress( IPAddress::Resolve( CurrAttrib.AsString() ) );
259  }else{
260  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + IPAddress::GetSerializableName() + ": Not Version 1.");
261  }
262  }else{
263  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,IPAddress::GetSerializableName() + " was not found in the provided XML node, which was expected.");
264  }
265  }
266 
268  { return "IPAddress"; }
269  }//Network
270 }//Mezzanine
271 
272 #endif
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
static const UInt16 IPv6BinaryLength
The amount of space needed in a buffer to store the binary representation of an IPv6 address...
Definition: ipaddress.h:66
static AddressContainer Resolve(const String &Address)
Resolves an IPv4 or IPv6 address as a String to it's binary representation.
Definition: ipaddress.cpp:90
static const UInt16 IPv6StringLength
The amount of space needed in a string to store the character representation of an IPv6 address...
Definition: ipaddress.h:70
Boole operator==(const IPAddress &Other) const
Equality operator.
Definition: ipaddress.cpp:215
IPAddress()
Class Constructor.
Definition: ipaddress.cpp:69
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
static const String IPv6LoopbackAddress
The loopback address for IPv6.
Definition: ipaddress.h:77
~IPAddress()
Class Destructor.
Definition: ipaddress.cpp:84
void ProtoDeSerialize(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite this object with it.
Definition: ipaddress.cpp:250
Thrown when the requested identity could not be found.
Definition: exception.h:94
NetworkLayerProtocol
This is an enum listing for recognized protocols on Layer 3 of the OSI model.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
const Char8 * AsString(const Char8 *def="") const
Attempts to convert the value of the attribute to a String and returns the results.
static const String IPv4BroadcastAddress
The broadcast address for IPv4.
Definition: ipaddress.h:75
bool Empty() const
Is this storing anything at all?
This implements the exception hiearchy for Mezzanine.
void SetBinaryAddress(const AddressContainer &Address)
Sets the binary form of the address being stored.
Definition: ipaddress.cpp:176
UInt32 GetV4Address(const Boole NBO=false) const
Gets a version 4 IP address value.
Definition: ipaddress.cpp:194
Internet Protocol version 6.
The interface for serialization.
bool SetValue(const Char8 *rhs)
Set the value of this.
uint16_t UInt16
An 16-bit unsigned integer.
Definition: datatypes.h:122
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
AddressContainer InternalAddress
A resizable vector to store the binary IP address regardless of version.
Definition: ipaddress.h:81
bool Empty() const
Is this storing anything at all?
This is a simple class for representing IP addresses used throughout the Network subsystem.
Definition: ipaddress.h:57
Used for error conditions.
const AddressContainer & GetBinaryAddress() const
Gets the stored binary address of this IPAddress.
Definition: ipaddress.cpp:179
static const String IPv4LoopbackAddress
The loopback address for IPv4.
Definition: ipaddress.h:73
String GetAsString() const
Gets this IPAddress in a human readable format.
Definition: ipaddress.cpp:173
static const UInt16 IPv4BinaryLength
The amount of space needed in a buffer to store the binary representation of an IPv4 address...
Definition: ipaddress.h:64
Network::NetworkLayerProtocol GetProtocol() const
Gets the type of IP address this is.
Definition: ipaddress.cpp:162
static const UInt16 IPv4StringLength
The amount of space needed in a string to store the character representation of an IPv4 address...
Definition: ipaddress.h:68
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
Boole operator!=(const IPAddress &Other) const
Inequality operator.
Definition: ipaddress.cpp:229
void SetV4Address(const UInt32 Address, const Boole NBO=false)
Sets a version 4 IP address value.
Definition: ipaddress.cpp:182
void ProtoSerialize(XML::Node &ParentNode) const
Convert this class to an XML::Node ready for serialization.
Definition: ipaddress.cpp:237
std::vector< Int8 > AddressContainer
Convenience type to store the binary representation of IP addresses.
Definition: ipaddress.h:61
void operator=(const IPAddress &Other)
Assignment operator.
Definition: ipaddress.cpp:212
const Char8 * Name() const
ptrdiff_tGet the name of this Node.
void SerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
static String GetSerializableName()
Get the name of the the XML tag the IPAddress class will leave behind as its instances are serialized...
Definition: ipaddress.cpp:267
Node AppendChild(NodeType Type=NodeElement)
Creates a Node and makes it a child of this one.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Internet Protocol version 4.
Attribute GetAttribute(const Char8 *Name) const
Attempt to get an Attribute on this Node with a given name.