PcapPlusPlus  24.09
IpAddress.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <stdint.h>
4 #include <string.h>
5 #include <string>
6 #include <algorithm>
7 #include <ostream>
8 #include <array>
9 #include <memory>
10 
12 
17 namespace pcpp
18 {
19 
20  // forward declarations
21  class IPv4Network;
22  class IPv6Network;
23 
24  // The implementation of the classes is based on document N4771 "Working Draft, C++ Extensions for Networking"
25  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf
26 
32  {
33  public:
37  IPv4Address() = default;
38 
43  IPv4Address(const uint32_t addrAsInt)
44  {
45  memcpy(m_Bytes.data(), &addrAsInt, sizeof(addrAsInt));
46  }
47 
52  IPv4Address(const uint8_t bytes[4])
53  {
54  memcpy(m_Bytes.data(), bytes, 4 * sizeof(uint8_t));
55  }
56 
61  IPv4Address(const std::array<uint8_t, 4>& bytes) : m_Bytes(bytes)
62  {}
63 
70  IPv4Address(const std::string& addrAsString);
71 
75  inline uint32_t toInt() const;
76 
80  const uint8_t* toBytes() const
81  {
82  return m_Bytes.data();
83  }
84 
88  const std::array<uint8_t, 4>& toByteArray() const
89  {
90  return m_Bytes;
91  }
92 
96  std::string toString() const;
97 
101  bool isMulticast() const;
102 
108  bool operator==(const IPv4Address& rhs) const
109  {
110  return toInt() == rhs.toInt();
111  }
112 
118  bool operator<(const IPv4Address& rhs) const
119  {
120  uint32_t intVal = toInt();
121  std::reverse(reinterpret_cast<uint8_t*>(&intVal), reinterpret_cast<uint8_t*>(&intVal) + sizeof(intVal));
122 
123  uint32_t rhsIntVal = rhs.toInt();
124  std::reverse(reinterpret_cast<uint8_t*>(&rhsIntVal),
125  reinterpret_cast<uint8_t*>(&rhsIntVal) + sizeof(rhsIntVal));
126 
127  return intVal < rhsIntVal;
128  }
129 
135  bool operator!=(const IPv4Address& rhs) const
136  {
137  return !(*this == rhs);
138  }
139 
145  bool matchNetwork(const IPv4Network& network) const;
146 
158  bool matchNetwork(const std::string& network) const;
159 
165  static bool isValidIPv4Address(const std::string& addrAsString);
166 
170  static const IPv4Address Zero;
171 
179  static const IPv4Address MulticastRangeUpperBound;
180 
181  private:
182  std::array<uint8_t, 4> m_Bytes = { 0 };
183  }; // class IPv4Address
184 
185  // Implementation of inline methods
186 
187  uint32_t IPv4Address::toInt() const
188  {
189  uint32_t addr;
190  memcpy(&addr, m_Bytes.data(), m_Bytes.size() * sizeof(uint8_t));
191  return addr;
192  }
193 
199  {
200  public:
204  IPv6Address() = default;
205 
210  IPv6Address(const uint8_t bytes[16])
211  {
212  memcpy(m_Bytes.data(), bytes, 16 * sizeof(uint8_t));
213  }
214 
219  IPv6Address(const std::array<uint8_t, 16>& bytes) : m_Bytes(bytes)
220  {}
221 
228  IPv6Address(const std::string& addrAsString);
229 
234  const uint8_t* toBytes() const
235  {
236  return m_Bytes.data();
237  }
238 
243  const std::array<uint8_t, 16>& toByteArray() const
244  {
245  return m_Bytes;
246  }
247 
252  std::string toString() const;
253 
258  bool isMulticast() const;
259 
265  bool operator==(const IPv6Address& rhs) const
266  {
267  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) == 0;
268  }
269 
275  bool operator<(const IPv6Address& rhs) const
276  {
277  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) < 0;
278  }
279 
285  bool operator!=(const IPv6Address& rhs) const
286  {
287  return !(*this == rhs);
288  }
289 
295  void copyTo(uint8_t** arr, size_t& length) const;
296 
302  void copyTo(uint8_t* arr) const
303  {
304  memcpy(arr, m_Bytes.data(), m_Bytes.size() * sizeof(uint8_t));
305  }
306 
312  bool matchNetwork(const IPv6Network& network) const;
313 
327  bool matchNetwork(const std::string& network) const;
328 
334  static bool isValidIPv6Address(const std::string& addrAsString);
335 
340  static const IPv6Address Zero;
341 
348 
349  private:
350  std::array<uint8_t, 16> m_Bytes = { 0 };
351  }; // class IPv6Address
352 
357  class IPAddress
358  {
359  public:
364  {
373  };
374 
379  {}
380 
385  IPAddress(const IPv4Address& addr) : m_Type(IPv4AddressType), m_IPv4(addr)
386  {}
387 
392  IPAddress(const IPv6Address& addr) : m_Type(IPv6AddressType), m_IPv6(addr)
393  {}
394 
401  IPAddress(const std::string& addrAsString);
402 
408  inline IPAddress& operator=(const IPv4Address& addr);
409 
415  inline IPAddress& operator=(const IPv6Address& addr);
416 
422  {
423  return static_cast<AddressType>(m_Type);
424  }
425 
430  std::string toString() const
431  {
432  return (getType() == IPv4AddressType) ? m_IPv4.toString() : m_IPv6.toString();
433  }
434 
438  bool isIPv4() const
439  {
440  return getType() == IPv4AddressType;
441  }
442 
446  bool isIPv6() const
447  {
448  return getType() == IPv6AddressType;
449  }
450 
455  bool isMulticast() const
456  {
457  return (getType() == IPv4AddressType) ? m_IPv4.isMulticast() : m_IPv6.isMulticast();
458  }
459 
464  const IPv4Address& getIPv4() const
465  {
466  return m_IPv4;
467  }
468 
473  const IPv6Address& getIPv6() const
474  {
475  return m_IPv6;
476  }
477 
481  bool isZero() const
482  {
483  return (getType() == IPv4AddressType) ? m_IPv4 == IPv4Address::Zero : m_IPv6 == IPv6Address::Zero;
484  }
485 
491  inline bool operator==(const IPAddress& rhs) const;
492 
498  inline bool operator<(const IPAddress& rhs) const;
499 
505  bool operator!=(const IPAddress& rhs) const
506  {
507  return !(*this == rhs);
508  }
509 
510  private:
511  uint8_t m_Type;
512  IPv4Address m_IPv4;
513  IPv6Address m_IPv6;
514  };
515 
516  // implementation of inline methods
517 
518  bool IPAddress::operator==(const IPAddress& rhs) const
519  {
520  if (isIPv4())
521  return rhs.isIPv4() ? (m_IPv4 == rhs.m_IPv4) : false;
522 
523  return rhs.isIPv6() ? m_IPv6 == rhs.m_IPv6 : false;
524  }
525 
526  bool IPAddress::operator<(const IPAddress& rhs) const
527  {
528  if (isIPv4())
529  {
530  // treat IPv4 as less than IPv6
531  // If current obj is IPv4 and other is IPv6 return true
532  return rhs.isIPv4() ? (m_IPv4 < rhs.m_IPv4) : true;
533  }
534  return rhs.isIPv6() ? m_IPv6 < rhs.m_IPv6 : false;
535  }
536 
538  {
539  m_Type = IPv4AddressType;
540  m_IPv4 = addr;
541  return *this;
542  }
543 
545  {
546  m_Type = IPv6AddressType;
547  m_IPv6 = addr;
548  return *this;
549  }
550 
556  {
557  public:
564  explicit IPv4Network(const IPv4Address& address) : IPv4Network(address, 32u)
565  {}
566 
575  IPv4Network(const IPv4Address& address, uint8_t prefixLen);
576 
587  IPv4Network(const IPv4Address& address, const std::string& netmask);
588 
599  IPv4Network(const std::string& addressAndNetmask);
600 
604  uint8_t getPrefixLen() const;
605 
609  std::string getNetmask() const
610  {
611  return IPv4Address(m_Mask).toString();
612  }
613 
618  {
619  return IPv4Address(m_NetworkPrefix);
620  }
621 
627 
633 
638  uint64_t getTotalAddressCount() const;
639 
644  bool includes(const IPv4Address& address) const;
645 
651  bool includes(const IPv4Network& network) const;
652 
657  std::string toString() const;
658 
659  private:
660  uint32_t m_NetworkPrefix;
661  uint32_t m_Mask;
662 
663  bool isValidNetmask(const IPv4Address& netmaskAddress);
664  void initFromAddressAndPrefixLength(const IPv4Address& address, uint8_t prefixLen);
665  void initFromAddressAndNetmask(const IPv4Address& address, const IPv4Address& netmaskAddress);
666  };
667 
673  {
674  public:
681  explicit IPv6Network(const IPv6Address& address) : IPv6Network(address, 128u)
682  {}
683 
692  IPv6Network(const IPv6Address& address, uint8_t prefixLen);
693 
704  IPv6Network(const IPv6Address& address, const std::string& netmask);
705 
716  IPv6Network(const std::string& addressAndNetmask);
717 
721  uint8_t getPrefixLen() const;
722 
726  std::string getNetmask() const
727  {
728  return IPv6Address(m_Mask).toString();
729  }
730 
735  {
736  return IPv6Address(m_NetworkPrefix);
737  }
738 
744 
750 
755  uint64_t getTotalAddressCount() const;
756 
761  bool includes(const IPv6Address& address) const;
762 
768  bool includes(const IPv6Network& network) const;
769 
774  std::string toString() const;
775 
776  private:
777  uint8_t m_NetworkPrefix[16];
778  uint8_t m_Mask[16];
779 
780  bool isValidNetmask(const IPv6Address& netmaskAddress);
781  void initFromAddressAndPrefixLength(const IPv6Address& address, uint8_t prefixLen);
782  void initFromAddressAndNetmask(const IPv6Address& address, const IPv6Address& netmaskAddress);
783  };
784 
789  class IPNetwork
790  {
791  public:
798  explicit IPNetwork(const IPAddress& address) : IPNetwork(address, address.isIPv4() ? 32u : 128u)
799  {}
800 
810  IPNetwork(const IPAddress& address, uint8_t prefixLen)
811  {
812  if (address.isIPv4())
813  {
814  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), prefixLen));
815  }
816  else
817  {
818  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), prefixLen));
819  }
820  }
821 
833  IPNetwork(const IPAddress& address, const std::string& netmask)
834  {
835  if (address.isIPv4())
836  {
837  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), netmask));
838  }
839  else
840  {
841  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), netmask));
842  }
843  }
844 
855  IPNetwork(const std::string& addressAndNetmask)
856  {
857  try
858  {
859  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(addressAndNetmask));
860  }
861  catch (const std::invalid_argument&)
862  {
863  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(addressAndNetmask));
864  }
865  }
866 
871  IPNetwork(const IPNetwork& other)
872  {
873  if (other.m_IPv4Network)
874  {
875  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(*other.m_IPv4Network));
876  }
877 
878  if (other.m_IPv6Network)
879  {
880  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(*other.m_IPv6Network));
881  }
882  }
883 
890  {
891  if (other.isIPv4Network())
892  {
893  return this->operator=(*other.m_IPv4Network);
894  }
895  else
896  {
897  return this->operator=(*other.m_IPv6Network);
898  }
899  }
900 
907  {
908  if (m_IPv4Network)
909  {
910  m_IPv4Network = nullptr;
911  }
912 
913  if (m_IPv6Network)
914  {
915  m_IPv6Network = nullptr;
916  }
917 
918  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(other));
919 
920  return *this;
921  }
922 
929  {
930  if (m_IPv4Network)
931  {
932  m_IPv4Network = nullptr;
933  }
934 
935  if (m_IPv6Network)
936  {
937  m_IPv6Network = nullptr;
938  }
939 
940  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(other));
941 
942  return *this;
943  }
944 
949  uint8_t getPrefixLen() const
950  {
951  return (m_IPv4Network != nullptr ? m_IPv4Network->getPrefixLen() : m_IPv6Network->getPrefixLen());
952  }
953 
958  std::string getNetmask() const
959  {
960  return (m_IPv4Network != nullptr ? m_IPv4Network->getNetmask() : m_IPv6Network->getNetmask());
961  }
962 
968  {
969  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getNetworkPrefix())
970  : IPAddress(m_IPv6Network->getNetworkPrefix()));
971  }
972 
978  {
979  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getLowestAddress())
980  : IPAddress(m_IPv6Network->getLowestAddress()));
981  }
982 
988  {
989  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getHighestAddress())
990  : IPAddress(m_IPv6Network->getHighestAddress()));
991  }
992 
998  uint64_t getTotalAddressCount() const
999  {
1000  return (m_IPv4Network != nullptr ? m_IPv4Network->getTotalAddressCount()
1001  : m_IPv6Network->getTotalAddressCount());
1002  }
1003 
1007  bool isIPv4Network() const
1008  {
1009  return m_IPv4Network != nullptr;
1010  }
1011 
1015  bool isIPv6Network() const
1016  {
1017  return m_IPv6Network != nullptr;
1018  }
1019 
1024  bool includes(const IPAddress& address) const
1025  {
1026  if (m_IPv4Network != nullptr)
1027  {
1028  if (address.isIPv6())
1029  {
1030  return false;
1031  }
1032 
1033  return m_IPv4Network->includes(address.getIPv4());
1034  }
1035  else
1036  {
1037  if (address.isIPv4())
1038  {
1039  return false;
1040  }
1041 
1042  return m_IPv6Network->includes(address.getIPv6());
1043  }
1044  }
1045 
1050  bool includes(const IPNetwork& network) const
1051  {
1052  if (m_IPv4Network != nullptr)
1053  {
1054  if (network.isIPv6Network())
1055  {
1056  return false;
1057  }
1058 
1059  return m_IPv4Network->includes(*network.m_IPv4Network);
1060  }
1061  else
1062  {
1063  if (network.isIPv4Network())
1064  {
1065  return false;
1066  }
1067 
1068  return m_IPv6Network->includes(*network.m_IPv6Network);
1069  }
1070  }
1071 
1076  std::string toString() const
1077  {
1078  return (m_IPv4Network != nullptr ? m_IPv4Network->toString() : m_IPv6Network->toString());
1079  }
1080 
1081  private:
1082  std::unique_ptr<IPv4Network> m_IPv4Network;
1083  std::unique_ptr<IPv6Network> m_IPv6Network;
1084  };
1085 } // namespace pcpp
1086 
1087 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv4Address& ipv4Address)
1088 {
1089  os << ipv4Address.toString();
1090  return os;
1091 }
1092 
1093 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv6Address& ipv6Address)
1094 {
1095  os << ipv6Address.toString();
1096  return os;
1097 }
1098 
1099 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPAddress& ipAddress)
1100 {
1101  os << ipAddress.toString();
1102  return os;
1103 }
1104 
1105 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv4Network& network)
1106 {
1107  os << network.toString();
1108  return os;
1109 }
1110 
1111 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv6Network& network)
1112 {
1113  os << network.toString();
1114  return os;
1115 }
1116 
1117 inline std::ostream& operator<<(std::ostream& os, const pcpp::IPNetwork& network)
1118 {
1119  os << network.toString();
1120  return os;
1121 }
Definition: IpAddress.h:358
IPAddress()
Definition: IpAddress.h:378
std::string toString() const
Definition: IpAddress.h:430
const IPv4Address & getIPv4() const
Definition: IpAddress.h:464
bool operator!=(const IPAddress &rhs) const
Definition: IpAddress.h:505
const IPv6Address & getIPv6() const
Definition: IpAddress.h:473
IPAddress(const std::string &addrAsString)
IPAddress(const IPv4Address &addr)
Definition: IpAddress.h:385
AddressType getType() const
Definition: IpAddress.h:421
bool operator<(const IPAddress &rhs) const
Definition: IpAddress.h:526
bool isIPv4() const
Definition: IpAddress.h:438
bool isZero() const
Definition: IpAddress.h:481
AddressType
Definition: IpAddress.h:364
@ IPv6AddressType
Definition: IpAddress.h:372
@ IPv4AddressType
Definition: IpAddress.h:368
IPAddress & operator=(const IPv4Address &addr)
Definition: IpAddress.h:537
bool isIPv6() const
Definition: IpAddress.h:446
bool isMulticast() const
Definition: IpAddress.h:455
bool operator==(const IPAddress &rhs) const
Definition: IpAddress.h:518
IPAddress(const IPv6Address &addr)
Definition: IpAddress.h:392
Definition: IpAddress.h:790
IPAddress getHighestAddress() const
Definition: IpAddress.h:987
IPNetwork & operator=(const IPv6Network &other)
Definition: IpAddress.h:928
IPAddress getLowestAddress() const
Definition: IpAddress.h:977
bool includes(const IPAddress &address) const
Definition: IpAddress.h:1024
bool isIPv6Network() const
Definition: IpAddress.h:1015
bool includes(const IPNetwork &network) const
Definition: IpAddress.h:1050
std::string toString() const
Definition: IpAddress.h:1076
bool isIPv4Network() const
Definition: IpAddress.h:1007
IPNetwork & operator=(const IPNetwork &other)
Definition: IpAddress.h:889
IPNetwork(const IPNetwork &other)
Definition: IpAddress.h:871
IPAddress getNetworkPrefix() const
Definition: IpAddress.h:967
IPNetwork(const IPAddress &address, const std::string &netmask)
Definition: IpAddress.h:833
uint64_t getTotalAddressCount() const
Definition: IpAddress.h:998
std::string getNetmask() const
Definition: IpAddress.h:958
uint8_t getPrefixLen() const
Definition: IpAddress.h:949
IPNetwork & operator=(const IPv4Network &other)
Definition: IpAddress.h:906
IPNetwork(const IPAddress &address)
Definition: IpAddress.h:798
IPNetwork(const std::string &addressAndNetmask)
Definition: IpAddress.h:855
IPNetwork(const IPAddress &address, uint8_t prefixLen)
Definition: IpAddress.h:810
Definition: IpAddress.h:32
static bool isValidIPv4Address(const std::string &addrAsString)
bool matchNetwork(const std::string &network) const
static const IPv4Address MulticastRangeLowerBound
Definition: IpAddress.h:178
IPv4Address(const std::array< uint8_t, 4 > &bytes)
Definition: IpAddress.h:61
bool matchNetwork(const IPv4Network &network) const
IPv4Address()=default
std::string toString() const
IPv4Address(const std::string &addrAsString)
const uint8_t * toBytes() const
Definition: IpAddress.h:80
bool operator!=(const IPv4Address &rhs) const
Definition: IpAddress.h:135
IPv4Address(const uint32_t addrAsInt)
Definition: IpAddress.h:43
IPv4Address(const uint8_t bytes[4])
Definition: IpAddress.h:52
bool operator==(const IPv4Address &rhs) const
Definition: IpAddress.h:108
bool operator<(const IPv4Address &rhs) const
Definition: IpAddress.h:118
const std::array< uint8_t, 4 > & toByteArray() const
Definition: IpAddress.h:88
uint32_t toInt() const
Definition: IpAddress.h:187
static const IPv4Address Zero
Definition: IpAddress.h:170
bool isMulticast() const
Definition: IpAddress.h:556
IPv4Network(const IPv4Address &address)
Definition: IpAddress.h:564
IPv4Address getLowestAddress() const
std::string getNetmask() const
Definition: IpAddress.h:609
IPv4Network(const IPv4Address &address, const std::string &netmask)
IPv4Address getHighestAddress() const
std::string toString() const
uint8_t getPrefixLen() const
bool includes(const IPv4Address &address) const
uint64_t getTotalAddressCount() const
IPv4Network(const IPv4Address &address, uint8_t prefixLen)
IPv4Address getNetworkPrefix() const
Definition: IpAddress.h:617
IPv4Network(const std::string &addressAndNetmask)
bool includes(const IPv4Network &network) const
Definition: IpAddress.h:199
static const IPv6Address MulticastRangeLowerBound
Definition: IpAddress.h:347
void copyTo(uint8_t *arr) const
Definition: IpAddress.h:302
void copyTo(uint8_t **arr, size_t &length) const
const uint8_t * toBytes() const
Definition: IpAddress.h:234
bool matchNetwork(const IPv6Network &network) const
IPv6Address(const uint8_t bytes[16])
Definition: IpAddress.h:210
static const IPv6Address Zero
Definition: IpAddress.h:340
bool matchNetwork(const std::string &network) const
bool operator<(const IPv6Address &rhs) const
Definition: IpAddress.h:275
bool operator!=(const IPv6Address &rhs) const
Definition: IpAddress.h:285
const std::array< uint8_t, 16 > & toByteArray() const
Definition: IpAddress.h:243
IPv6Address(const std::string &addrAsString)
bool isMulticast() const
IPv6Address()=default
static bool isValidIPv6Address(const std::string &addrAsString)
std::string toString() const
bool operator==(const IPv6Address &rhs) const
Definition: IpAddress.h:265
IPv6Address(const std::array< uint8_t, 16 > &bytes)
Definition: IpAddress.h:219
Definition: IpAddress.h:673
IPv6Network(const std::string &addressAndNetmask)
IPv6Address getHighestAddress() const
uint8_t getPrefixLen() const
std::string getNetmask() const
Definition: IpAddress.h:726
bool includes(const IPv6Network &network) const
IPv6Address getLowestAddress() const
IPv6Network(const IPv6Address &address, const std::string &netmask)
IPv6Network(const IPv6Address &address, uint8_t prefixLen)
uint64_t getTotalAddressCount() const
IPv6Address getNetworkPrefix() const
Definition: IpAddress.h:734
std::string toString() const
bool includes(const IPv6Address &address) const
IPv6Network(const IPv6Address &address)
Definition: IpAddress.h:681
The main namespace for the PcapPlusPlus lib.