PcapPlusPlus  Next
IpAddress.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <cstring>
5 #include <string>
6 #include <algorithm>
7 #include <ostream>
8 #include <array>
9 #include <memory>
10 
11 #include "DeprecationUtils.h"
12 
14 
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 
30  {
31  public:
33  IPv4Address() = default;
34 
37  IPv4Address(const uint32_t addrAsInt)
38  {
39  memcpy(m_Bytes.data(), &addrAsInt, sizeof(addrAsInt));
40  }
41 
46  IPv4Address(const uint8_t bytes[4]) : IPv4Address(bytes, 4)
47  {}
48 
54  IPv4Address(const uint8_t* bytes, size_t size);
55 
58  IPv4Address(const std::array<uint8_t, 4>& bytes) : m_Bytes(bytes)
59  {}
60 
64  IPv4Address(const std::string& addrAsString);
65 
67  inline uint32_t toInt() const;
68 
70  const uint8_t* toBytes() const
71  {
72  return m_Bytes.data();
73  }
74 
76  const std::array<uint8_t, 4>& toByteArray() const
77  {
78  return m_Bytes;
79  }
80 
82  std::string toString() const;
83 
85  bool isMulticast() const;
86 
90  bool operator==(const IPv4Address& rhs) const
91  {
92  return toInt() == rhs.toInt();
93  }
94 
98  bool operator<(const IPv4Address& rhs) const
99  {
100  uint32_t intVal = toInt();
101  std::reverse(reinterpret_cast<uint8_t*>(&intVal), reinterpret_cast<uint8_t*>(&intVal) + sizeof(intVal));
102 
103  uint32_t rhsIntVal = rhs.toInt();
104  std::reverse(reinterpret_cast<uint8_t*>(&rhsIntVal),
105  reinterpret_cast<uint8_t*>(&rhsIntVal) + sizeof(rhsIntVal));
106 
107  return intVal < rhsIntVal;
108  }
109 
113  bool operator!=(const IPv4Address& rhs) const
114  {
115  return !(*this == rhs);
116  }
117 
121  bool matchNetwork(const IPv4Network& network) const;
122 
132  bool matchNetwork(const std::string& network) const;
133 
137  static bool isValidIPv4Address(const std::string& addrAsString);
138 
140  static const IPv4Address Zero;
141 
147  static const IPv4Address MulticastRangeUpperBound;
148 
149  private:
150  std::array<uint8_t, 4> m_Bytes = { 0 };
151  }; // class IPv4Address
152 
153  // Implementation of inline methods
154 
155  uint32_t IPv4Address::toInt() const
156  {
157  uint32_t addr = 0;
158  memcpy(&addr, m_Bytes.data(), m_Bytes.size() * sizeof(uint8_t));
159  return addr;
160  }
161 
165  {
166  public:
168  IPv6Address() = default;
169 
174  IPv6Address(const uint8_t bytes[16]) : IPv6Address(bytes, 16)
175  {}
176 
182  IPv6Address(const uint8_t* bytes, size_t size);
183 
186  IPv6Address(const std::array<uint8_t, 16>& bytes) : m_Bytes(bytes)
187  {}
188 
192  IPv6Address(const std::string& addrAsString);
193 
196  const uint8_t* toBytes() const
197  {
198  return m_Bytes.data();
199  }
200 
203  const std::array<uint8_t, 16>& toByteArray() const
204  {
205  return m_Bytes;
206  }
207 
210  std::string toString() const;
211 
214  bool isMulticast() const;
215 
219  bool operator==(const IPv6Address& rhs) const
220  {
221  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) == 0;
222  }
223 
227  bool operator<(const IPv6Address& rhs) const
228  {
229  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) < 0;
230  }
231 
235  bool operator!=(const IPv6Address& rhs) const
236  {
237  return !(*this == rhs);
238  }
239 
245  PCPP_DEPRECATED("Use copyToNewBuffer instead.")
246  void copyTo(uint8_t** arr, size_t& length) const;
247 
254  void copyTo(uint8_t* arr) const
255  {
256  copyTo(arr, 16);
257  }
258 
268  size_t copyTo(uint8_t* buffer, size_t size) const;
269 
277  bool copyToNewBuffer(uint8_t** buffer, size_t& size) const;
278 
282  bool matchNetwork(const IPv6Network& network) const;
283 
295  bool matchNetwork(const std::string& network) const;
296 
300  static bool isValidIPv6Address(const std::string& addrAsString);
301 
304  static const IPv6Address Zero;
305 
310 
311  private:
312  std::array<uint8_t, 16> m_Bytes = { 0 };
313  }; // class IPv6Address
314 
317  class IPAddress
318  {
319  public:
321  enum AddressType : uint8_t
322  {
327  };
328 
331  {}
332 
335  IPAddress(const IPv4Address& addr) : m_Type(IPv4AddressType), m_IPv4(addr)
336  {}
337 
340  IPAddress(const IPv6Address& addr) : m_Type(IPv6AddressType), m_IPv6(addr)
341  {}
342 
346  IPAddress(const std::string& addrAsString);
347 
351  inline IPAddress& operator=(const IPv4Address& addr);
352 
356  inline IPAddress& operator=(const IPv6Address& addr);
357 
361  {
362  return static_cast<AddressType>(m_Type);
363  }
364 
367  std::string toString() const
368  {
369  return (getType() == IPv4AddressType) ? m_IPv4.toString() : m_IPv6.toString();
370  }
371 
373  bool isIPv4() const
374  {
375  return getType() == IPv4AddressType;
376  }
377 
379  bool isIPv6() const
380  {
381  return getType() == IPv6AddressType;
382  }
383 
386  bool isMulticast() const
387  {
388  return (getType() == IPv4AddressType) ? m_IPv4.isMulticast() : m_IPv6.isMulticast();
389  }
390 
393  const IPv4Address& getIPv4() const
394  {
395  return m_IPv4;
396  }
397 
400  const IPv6Address& getIPv6() const
401  {
402  return m_IPv6;
403  }
404 
406  bool isZero() const
407  {
408  return (getType() == IPv4AddressType) ? m_IPv4 == IPv4Address::Zero : m_IPv6 == IPv6Address::Zero;
409  }
410 
414  inline bool operator==(const IPAddress& rhs) const;
415 
419  inline bool operator<(const IPAddress& rhs) const;
420 
424  bool operator!=(const IPAddress& rhs) const
425  {
426  return !(*this == rhs);
427  }
428 
429  private:
430  uint8_t m_Type;
431  IPv4Address m_IPv4;
432  IPv6Address m_IPv6;
433  };
434 
435  // implementation of inline methods
436 
437  bool IPAddress::operator==(const IPAddress& rhs) const
438  {
439  if (isIPv4())
440  {
441  return rhs.isIPv4() ? (m_IPv4 == rhs.m_IPv4) : false;
442  }
443 
444  return rhs.isIPv6() ? m_IPv6 == rhs.m_IPv6 : false;
445  }
446 
447  bool IPAddress::operator<(const IPAddress& rhs) const
448  {
449  if (isIPv4())
450  {
451  // treat IPv4 as less than IPv6
452  // If current obj is IPv4 and other is IPv6 return true
453  return rhs.isIPv4() ? (m_IPv4 < rhs.m_IPv4) : true;
454  }
455  return rhs.isIPv6() ? m_IPv6 < rhs.m_IPv6 : false;
456  }
457 
459  {
460  m_Type = IPv4AddressType;
461  m_IPv4 = addr;
462  return *this;
463  }
464 
466  {
467  m_Type = IPv6AddressType;
468  m_IPv6 = addr;
469  return *this;
470  }
471 
475  {
476  public:
480  explicit IPv4Network(const IPv4Address& address) : IPv4Network(address, 32U)
481  {}
482 
489  IPv4Network(const IPv4Address& address, uint8_t prefixLen);
490 
499  IPv4Network(const IPv4Address& address, const std::string& netmask);
500 
509  IPv4Network(const std::string& addressAndNetmask);
510 
512  uint8_t getPrefixLen() const;
513 
515  std::string getNetmask() const
516  {
517  return IPv4Address(m_Mask).toString();
518  }
519 
522  {
523  return m_NetworkPrefix;
524  }
525 
529 
533 
536  uint64_t getTotalAddressCount() const;
537 
540  bool includes(const IPv4Address& address) const;
541 
545  bool includes(const IPv4Network& network) const;
546 
549  std::string toString() const;
550 
551  private:
552  uint32_t m_NetworkPrefix{};
553  uint32_t m_Mask{};
554 
555  static bool isValidNetmask(const IPv4Address& netmaskAddress);
556  void initFromAddressAndPrefixLength(const IPv4Address& address, uint8_t prefixLen);
557  void initFromAddressAndNetmask(const IPv4Address& address, const IPv4Address& netmaskAddress);
558  };
559 
563  {
564  public:
568  explicit IPv6Network(const IPv6Address& address) : IPv6Network(address, 128U)
569  {}
570 
577  IPv6Network(const IPv6Address& address, uint8_t prefixLen);
578 
587  IPv6Network(const IPv6Address& address, const std::string& netmask);
588 
597  IPv6Network(const std::string& addressAndNetmask);
598 
600  uint8_t getPrefixLen() const;
601 
603  std::string getNetmask() const
604  {
605  return IPv6Address(m_Mask).toString();
606  }
607 
610  {
611  return { m_NetworkPrefix };
612  }
613 
617 
621 
624  uint64_t getTotalAddressCount() const;
625 
628  bool includes(const IPv6Address& address) const;
629 
633  bool includes(const IPv6Network& network) const;
634 
637  std::string toString() const;
638 
639  private:
640  uint8_t m_NetworkPrefix[16]{};
641  uint8_t m_Mask[16]{};
642 
643  static bool isValidNetmask(const IPv6Address& netmaskAddress);
644  void initFromAddressAndPrefixLength(const IPv6Address& address, uint8_t prefixLen);
645  void initFromAddressAndNetmask(const IPv6Address& address, const IPv6Address& netmaskAddress);
646  };
647 
650  class IPNetwork
651  {
652  public:
656  explicit IPNetwork(const IPAddress& address) : IPNetwork(address, address.isIPv4() ? 32U : 128U)
657  {}
658 
666  IPNetwork(const IPAddress& address, uint8_t prefixLen)
667  {
668  if (address.isIPv4())
669  {
670  m_IPv4Network = std::make_unique<IPv4Network>(address.getIPv4(), prefixLen);
671  }
672  else
673  {
674  m_IPv6Network = std::make_unique<IPv6Network>(address.getIPv6(), prefixLen);
675  }
676  }
677 
687  IPNetwork(const IPAddress& address, const std::string& netmask)
688  {
689  if (address.isIPv4())
690  {
691  m_IPv4Network = std::make_unique<IPv4Network>(address.getIPv4(), netmask);
692  }
693  else
694  {
695  m_IPv6Network = std::make_unique<IPv6Network>(address.getIPv6(), netmask);
696  }
697  }
698 
707  IPNetwork(const std::string& addressAndNetmask)
708  {
709  try
710  {
711  m_IPv4Network = std::make_unique<IPv4Network>(addressAndNetmask);
712  }
713  catch (const std::invalid_argument&)
714  {
715  m_IPv6Network = std::make_unique<IPv6Network>(addressAndNetmask);
716  }
717  }
718 
721  IPNetwork(const IPNetwork& other)
722  {
723  if (other.m_IPv4Network)
724  {
725  m_IPv4Network = std::make_unique<IPv4Network>(*other.m_IPv4Network);
726  }
727 
728  if (other.m_IPv6Network)
729  {
730  m_IPv6Network = std::make_unique<IPv6Network>(*other.m_IPv6Network);
731  }
732  }
733 
738  {
739  // NOLINTBEGIN(cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator)
740  if (other.isIPv4Network())
741  {
742  return this->operator=(*other.m_IPv4Network);
743  }
744 
745  return this->operator=(*other.m_IPv6Network);
746  // NOLINTEND(cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator)
747  }
748 
753  {
754  // Create the new instance first to maintain strong exception guarantee.
755  m_IPv4Network = std::make_unique<IPv4Network>(other);
756  m_IPv6Network = nullptr;
757  return *this;
758  }
759 
764  {
765  // Create the new instance first to maintain strong exception guarantee.
766  m_IPv6Network = std::make_unique<IPv6Network>(other);
767  m_IPv4Network = nullptr;
768  return *this;
769  }
770 
773  uint8_t getPrefixLen() const
774  {
775  return (m_IPv4Network != nullptr ? m_IPv4Network->getPrefixLen() : m_IPv6Network->getPrefixLen());
776  }
777 
780  std::string getNetmask() const
781  {
782  return (m_IPv4Network != nullptr ? m_IPv4Network->getNetmask() : m_IPv6Network->getNetmask());
783  }
784 
788  {
789  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getNetworkPrefix())
790  : IPAddress(m_IPv6Network->getNetworkPrefix()));
791  }
792 
796  {
797  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getLowestAddress())
798  : IPAddress(m_IPv6Network->getLowestAddress()));
799  }
800 
804  {
805  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getHighestAddress())
806  : IPAddress(m_IPv6Network->getHighestAddress()));
807  }
808 
812  uint64_t getTotalAddressCount() const
813  {
814  return (m_IPv4Network != nullptr ? m_IPv4Network->getTotalAddressCount()
815  : m_IPv6Network->getTotalAddressCount());
816  }
817 
819  bool isIPv4Network() const
820  {
821  return m_IPv4Network != nullptr;
822  }
823 
825  bool isIPv6Network() const
826  {
827  return m_IPv6Network != nullptr;
828  }
829 
832  bool includes(const IPAddress& address) const
833  {
834  if (m_IPv4Network != nullptr)
835  {
836  if (address.isIPv6())
837  {
838  return false;
839  }
840 
841  return m_IPv4Network->includes(address.getIPv4());
842  }
843 
844  if (address.isIPv4())
845  {
846  return false;
847  }
848 
849  return m_IPv6Network->includes(address.getIPv6());
850  }
851 
854  bool includes(const IPNetwork& network) const
855  {
856  if (m_IPv4Network != nullptr)
857  {
858  if (network.isIPv6Network())
859  {
860  return false;
861  }
862 
863  return m_IPv4Network->includes(*network.m_IPv4Network);
864  }
865 
866  if (network.isIPv4Network())
867  {
868  return false;
869  }
870 
871  return m_IPv6Network->includes(*network.m_IPv6Network);
872  }
873 
876  std::string toString() const
877  {
878  return (m_IPv4Network != nullptr ? m_IPv4Network->toString() : m_IPv6Network->toString());
879  }
880 
881  private:
882  std::unique_ptr<IPv4Network> m_IPv4Network;
883  std::unique_ptr<IPv6Network> m_IPv6Network;
884  };
885 
886  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv4Address& ipv4Address)
887  {
888  oss << ipv4Address.toString();
889  return oss;
890  }
891 
892  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv6Address& ipv6Address)
893  {
894  oss << ipv6Address.toString();
895  return oss;
896  }
897 
898  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPAddress& ipAddress)
899  {
900  oss << ipAddress.toString();
901  return oss;
902  }
903 
904  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv4Network& network)
905  {
906  oss << network.toString();
907  return oss;
908  }
909 
910  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv6Network& network)
911  {
912  oss << network.toString();
913  return oss;
914  }
915 
916  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPNetwork& network)
917  {
918  oss << network.toString();
919  return oss;
920  }
921 } // namespace pcpp
Definition: IpAddress.h:318
IPAddress()
A default constructor that creates an instance of the class with unspecified IPv4 address.
Definition: IpAddress.h:330
std::string toString() const
Definition: IpAddress.h:367
AddressType
An enum representing the address type: IPv4 or IPv6.
Definition: IpAddress.h:322
@ IPv6AddressType
IPv6 address type.
Definition: IpAddress.h:326
@ IPv4AddressType
IPv4 address type.
Definition: IpAddress.h:324
const IPv4Address & getIPv4() const
Definition: IpAddress.h:393
bool operator!=(const IPAddress &rhs) const
Definition: IpAddress.h:424
const IPv6Address & getIPv6() const
Definition: IpAddress.h:400
IPAddress(const std::string &addrAsString)
IPAddress(const IPv4Address &addr)
Definition: IpAddress.h:335
AddressType getType() const
Definition: IpAddress.h:360
bool operator<(const IPAddress &rhs) const
Definition: IpAddress.h:447
bool isIPv4() const
Definition: IpAddress.h:373
bool isZero() const
Definition: IpAddress.h:406
IPAddress & operator=(const IPv4Address &addr)
Definition: IpAddress.h:458
bool isIPv6() const
Definition: IpAddress.h:379
bool isMulticast() const
Definition: IpAddress.h:386
bool operator==(const IPAddress &rhs) const
Definition: IpAddress.h:437
IPAddress(const IPv6Address &addr)
Definition: IpAddress.h:340
Definition: IpAddress.h:651
IPAddress getHighestAddress() const
Definition: IpAddress.h:803
IPNetwork & operator=(const IPv6Network &other)
Definition: IpAddress.h:763
IPAddress getLowestAddress() const
Definition: IpAddress.h:795
bool includes(const IPAddress &address) const
Definition: IpAddress.h:832
bool isIPv6Network() const
Definition: IpAddress.h:825
bool includes(const IPNetwork &network) const
Definition: IpAddress.h:854
std::string toString() const
Definition: IpAddress.h:876
bool isIPv4Network() const
Definition: IpAddress.h:819
IPNetwork & operator=(const IPNetwork &other)
Definition: IpAddress.h:737
IPNetwork(const IPNetwork &other)
Definition: IpAddress.h:721
IPAddress getNetworkPrefix() const
Definition: IpAddress.h:787
IPNetwork(const IPAddress &address, const std::string &netmask)
Definition: IpAddress.h:687
uint64_t getTotalAddressCount() const
Definition: IpAddress.h:812
std::string getNetmask() const
Definition: IpAddress.h:780
uint8_t getPrefixLen() const
Definition: IpAddress.h:773
IPNetwork & operator=(const IPv4Network &other)
Definition: IpAddress.h:752
IPNetwork(const IPAddress &address)
Definition: IpAddress.h:656
IPNetwork(const std::string &addressAndNetmask)
Definition: IpAddress.h:707
IPNetwork(const IPAddress &address, uint8_t prefixLen)
Definition: IpAddress.h:666
Definition: IpAddress.h:30
static bool isValidIPv4Address(const std::string &addrAsString)
bool matchNetwork(const std::string &network) const
static const IPv4Address MulticastRangeLowerBound
Definition: IpAddress.h:146
IPv4Address(const std::array< uint8_t, 4 > &bytes)
Definition: IpAddress.h:58
bool matchNetwork(const IPv4Network &network) const
IPv4Address()=default
A default constructor that creates an instance of the class with the zero-initialized address.
std::string toString() const
IPv4Address(const std::string &addrAsString)
const uint8_t * toBytes() const
Definition: IpAddress.h:70
bool operator!=(const IPv4Address &rhs) const
Definition: IpAddress.h:113
IPv4Address(const uint8_t *bytes, size_t size)
IPv4Address(const uint32_t addrAsInt)
Definition: IpAddress.h:37
IPv4Address(const uint8_t bytes[4])
Definition: IpAddress.h:46
bool operator==(const IPv4Address &rhs) const
Definition: IpAddress.h:90
bool operator<(const IPv4Address &rhs) const
Definition: IpAddress.h:98
const std::array< uint8_t, 4 > & toByteArray() const
Definition: IpAddress.h:76
uint32_t toInt() const
Definition: IpAddress.h:155
static const IPv4Address Zero
A static value representing a zero value of IPv4 address, meaning address of value "0....
Definition: IpAddress.h:140
bool isMulticast() const
Definition: IpAddress.h:475
IPv4Network(const IPv4Address &address)
Definition: IpAddress.h:480
IPv4Address getLowestAddress() const
std::string getNetmask() const
Definition: IpAddress.h:515
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:521
IPv4Network(const std::string &addressAndNetmask)
bool includes(const IPv4Network &network) const
Definition: IpAddress.h:165
static const IPv6Address MulticastRangeLowerBound
Definition: IpAddress.h:309
void copyTo(uint8_t **arr, size_t &length) const
const uint8_t * toBytes() const
Definition: IpAddress.h:196
bool matchNetwork(const IPv6Network &network) const
IPv6Address(const uint8_t bytes[16])
Definition: IpAddress.h:174
IPv6Address(const uint8_t *bytes, size_t size)
A constructor that creates an instance of the class out of a 16-byte array.
static const IPv6Address Zero
Definition: IpAddress.h:304
bool matchNetwork(const std::string &network) const
bool operator<(const IPv6Address &rhs) const
Definition: IpAddress.h:227
bool operator!=(const IPv6Address &rhs) const
Definition: IpAddress.h:235
const std::array< uint8_t, 16 > & toByteArray() const
Definition: IpAddress.h:203
IPv6Address(const std::string &addrAsString)
bool copyToNewBuffer(uint8_t **buffer, size_t &size) const
Allocates a new buffer and copies the address value to it. The user is responsible for deallocating t...
bool isMulticast() const
size_t copyTo(uint8_t *buffer, size_t size) const
Copies the address value to a user-provided buffer.
IPv6Address()=default
A default constructor that creates an instance of the class with the zero-initialized address.
static bool isValidIPv6Address(const std::string &addrAsString)
std::string toString() const
bool operator==(const IPv6Address &rhs) const
Definition: IpAddress.h:219
IPv6Address(const std::array< uint8_t, 16 > &bytes)
Definition: IpAddress.h:186
Definition: IpAddress.h:563
IPv6Network(const std::string &addressAndNetmask)
IPv6Address getHighestAddress() const
uint8_t getPrefixLen() const
std::string getNetmask() const
Definition: IpAddress.h:603
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:609
std::string toString() const
bool includes(const IPv6Address &address) const
IPv6Network(const IPv6Address &address)
Definition: IpAddress.h:568
The main namespace for the PcapPlusPlus lib.