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 
12 
15 namespace pcpp
16 {
17 
18  // forward declarations
19  class IPv4Network;
20  class IPv6Network;
21 
22  // The implementation of the classes is based on document N4771 "Working Draft, C++ Extensions for Networking"
23  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf
24 
28  {
29  public:
31  IPv4Address() = default;
32 
35  IPv4Address(const uint32_t addrAsInt)
36  {
37  memcpy(m_Bytes.data(), &addrAsInt, sizeof(addrAsInt));
38  }
39 
42  IPv4Address(const uint8_t bytes[4])
43  {
44  memcpy(m_Bytes.data(), bytes, 4 * sizeof(uint8_t));
45  }
46 
49  IPv4Address(const std::array<uint8_t, 4>& bytes) : m_Bytes(bytes)
50  {}
51 
55  IPv4Address(const std::string& addrAsString);
56 
58  inline uint32_t toInt() const;
59 
61  const uint8_t* toBytes() const
62  {
63  return m_Bytes.data();
64  }
65 
67  const std::array<uint8_t, 4>& toByteArray() const
68  {
69  return m_Bytes;
70  }
71 
73  std::string toString() const;
74 
76  bool isMulticast() const;
77 
81  bool operator==(const IPv4Address& rhs) const
82  {
83  return toInt() == rhs.toInt();
84  }
85 
89  bool operator<(const IPv4Address& rhs) const
90  {
91  uint32_t intVal = toInt();
92  std::reverse(reinterpret_cast<uint8_t*>(&intVal), reinterpret_cast<uint8_t*>(&intVal) + sizeof(intVal));
93 
94  uint32_t rhsIntVal = rhs.toInt();
95  std::reverse(reinterpret_cast<uint8_t*>(&rhsIntVal),
96  reinterpret_cast<uint8_t*>(&rhsIntVal) + sizeof(rhsIntVal));
97 
98  return intVal < rhsIntVal;
99  }
100 
104  bool operator!=(const IPv4Address& rhs) const
105  {
106  return !(*this == rhs);
107  }
108 
112  bool matchNetwork(const IPv4Network& network) const;
113 
123  bool matchNetwork(const std::string& network) const;
124 
128  static bool isValidIPv4Address(const std::string& addrAsString);
129 
131  static const IPv4Address Zero;
132 
138  static const IPv4Address MulticastRangeUpperBound;
139 
140  private:
141  std::array<uint8_t, 4> m_Bytes = { 0 };
142  }; // class IPv4Address
143 
144  // Implementation of inline methods
145 
146  uint32_t IPv4Address::toInt() const
147  {
148  uint32_t addr = 0;
149  memcpy(&addr, m_Bytes.data(), m_Bytes.size() * sizeof(uint8_t));
150  return addr;
151  }
152 
156  {
157  public:
159  IPv6Address() = default;
160 
163  IPv6Address(const uint8_t bytes[16])
164  {
165  memcpy(m_Bytes.data(), bytes, 16 * sizeof(uint8_t));
166  }
167 
170  IPv6Address(const std::array<uint8_t, 16>& bytes) : m_Bytes(bytes)
171  {}
172 
176  IPv6Address(const std::string& addrAsString);
177 
180  const uint8_t* toBytes() const
181  {
182  return m_Bytes.data();
183  }
184 
187  const std::array<uint8_t, 16>& toByteArray() const
188  {
189  return m_Bytes;
190  }
191 
194  std::string toString() const;
195 
198  bool isMulticast() const;
199 
203  bool operator==(const IPv6Address& rhs) const
204  {
205  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) == 0;
206  }
207 
211  bool operator<(const IPv6Address& rhs) const
212  {
213  return memcmp(toBytes(), rhs.toBytes(), sizeof(m_Bytes)) < 0;
214  }
215 
219  bool operator!=(const IPv6Address& rhs) const
220  {
221  return !(*this == rhs);
222  }
223 
227  void copyTo(uint8_t** arr, size_t& length) const;
228 
232  void copyTo(uint8_t* arr) const
233  {
234  memcpy(arr, m_Bytes.data(), m_Bytes.size() * sizeof(uint8_t));
235  }
236 
240  bool matchNetwork(const IPv6Network& network) const;
241 
253  bool matchNetwork(const std::string& network) const;
254 
258  static bool isValidIPv6Address(const std::string& addrAsString);
259 
262  static const IPv6Address Zero;
263 
268 
269  private:
270  std::array<uint8_t, 16> m_Bytes = { 0 };
271  }; // class IPv6Address
272 
275  class IPAddress
276  {
277  public:
279  enum AddressType : uint8_t
280  {
285  };
286 
289  {}
290 
293  IPAddress(const IPv4Address& addr) : m_Type(IPv4AddressType), m_IPv4(addr)
294  {}
295 
298  IPAddress(const IPv6Address& addr) : m_Type(IPv6AddressType), m_IPv6(addr)
299  {}
300 
304  IPAddress(const std::string& addrAsString);
305 
309  inline IPAddress& operator=(const IPv4Address& addr);
310 
314  inline IPAddress& operator=(const IPv6Address& addr);
315 
319  {
320  return static_cast<AddressType>(m_Type);
321  }
322 
325  std::string toString() const
326  {
327  return (getType() == IPv4AddressType) ? m_IPv4.toString() : m_IPv6.toString();
328  }
329 
331  bool isIPv4() const
332  {
333  return getType() == IPv4AddressType;
334  }
335 
337  bool isIPv6() const
338  {
339  return getType() == IPv6AddressType;
340  }
341 
344  bool isMulticast() const
345  {
346  return (getType() == IPv4AddressType) ? m_IPv4.isMulticast() : m_IPv6.isMulticast();
347  }
348 
351  const IPv4Address& getIPv4() const
352  {
353  return m_IPv4;
354  }
355 
358  const IPv6Address& getIPv6() const
359  {
360  return m_IPv6;
361  }
362 
364  bool isZero() const
365  {
366  return (getType() == IPv4AddressType) ? m_IPv4 == IPv4Address::Zero : m_IPv6 == IPv6Address::Zero;
367  }
368 
372  inline bool operator==(const IPAddress& rhs) const;
373 
377  inline bool operator<(const IPAddress& rhs) const;
378 
382  bool operator!=(const IPAddress& rhs) const
383  {
384  return !(*this == rhs);
385  }
386 
387  private:
388  uint8_t m_Type;
389  IPv4Address m_IPv4;
390  IPv6Address m_IPv6;
391  };
392 
393  // implementation of inline methods
394 
395  bool IPAddress::operator==(const IPAddress& rhs) const
396  {
397  if (isIPv4())
398  {
399  return rhs.isIPv4() ? (m_IPv4 == rhs.m_IPv4) : false;
400  }
401 
402  return rhs.isIPv6() ? m_IPv6 == rhs.m_IPv6 : false;
403  }
404 
405  bool IPAddress::operator<(const IPAddress& rhs) const
406  {
407  if (isIPv4())
408  {
409  // treat IPv4 as less than IPv6
410  // If current obj is IPv4 and other is IPv6 return true
411  return rhs.isIPv4() ? (m_IPv4 < rhs.m_IPv4) : true;
412  }
413  return rhs.isIPv6() ? m_IPv6 < rhs.m_IPv6 : false;
414  }
415 
417  {
418  m_Type = IPv4AddressType;
419  m_IPv4 = addr;
420  return *this;
421  }
422 
424  {
425  m_Type = IPv6AddressType;
426  m_IPv6 = addr;
427  return *this;
428  }
429 
433  {
434  public:
438  explicit IPv4Network(const IPv4Address& address) : IPv4Network(address, 32U)
439  {}
440 
447  IPv4Network(const IPv4Address& address, uint8_t prefixLen);
448 
457  IPv4Network(const IPv4Address& address, const std::string& netmask);
458 
467  IPv4Network(const std::string& addressAndNetmask);
468 
470  uint8_t getPrefixLen() const;
471 
473  std::string getNetmask() const
474  {
475  return IPv4Address(m_Mask).toString();
476  }
477 
480  {
481  return m_NetworkPrefix;
482  }
483 
487 
491 
494  uint64_t getTotalAddressCount() const;
495 
498  bool includes(const IPv4Address& address) const;
499 
503  bool includes(const IPv4Network& network) const;
504 
507  std::string toString() const;
508 
509  private:
510  uint32_t m_NetworkPrefix{};
511  uint32_t m_Mask{};
512 
513  static bool isValidNetmask(const IPv4Address& netmaskAddress);
514  void initFromAddressAndPrefixLength(const IPv4Address& address, uint8_t prefixLen);
515  void initFromAddressAndNetmask(const IPv4Address& address, const IPv4Address& netmaskAddress);
516  };
517 
521  {
522  public:
526  explicit IPv6Network(const IPv6Address& address) : IPv6Network(address, 128U)
527  {}
528 
535  IPv6Network(const IPv6Address& address, uint8_t prefixLen);
536 
545  IPv6Network(const IPv6Address& address, const std::string& netmask);
546 
555  IPv6Network(const std::string& addressAndNetmask);
556 
558  uint8_t getPrefixLen() const;
559 
561  std::string getNetmask() const
562  {
563  return IPv6Address(m_Mask).toString();
564  }
565 
568  {
569  return { m_NetworkPrefix };
570  }
571 
575 
579 
582  uint64_t getTotalAddressCount() const;
583 
586  bool includes(const IPv6Address& address) const;
587 
591  bool includes(const IPv6Network& network) const;
592 
595  std::string toString() const;
596 
597  private:
598  uint8_t m_NetworkPrefix[16]{};
599  uint8_t m_Mask[16]{};
600 
601  static bool isValidNetmask(const IPv6Address& netmaskAddress);
602  void initFromAddressAndPrefixLength(const IPv6Address& address, uint8_t prefixLen);
603  void initFromAddressAndNetmask(const IPv6Address& address, const IPv6Address& netmaskAddress);
604  };
605 
608  class IPNetwork
609  {
610  public:
614  explicit IPNetwork(const IPAddress& address) : IPNetwork(address, address.isIPv4() ? 32U : 128U)
615  {}
616 
624  IPNetwork(const IPAddress& address, uint8_t prefixLen)
625  {
626  if (address.isIPv4())
627  {
628  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), prefixLen));
629  }
630  else
631  {
632  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), prefixLen));
633  }
634  }
635 
645  IPNetwork(const IPAddress& address, const std::string& netmask)
646  {
647  if (address.isIPv4())
648  {
649  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), netmask));
650  }
651  else
652  {
653  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), netmask));
654  }
655  }
656 
665  IPNetwork(const std::string& addressAndNetmask)
666  {
667  try
668  {
669  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(addressAndNetmask));
670  }
671  catch (const std::invalid_argument&)
672  {
673  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(addressAndNetmask));
674  }
675  }
676 
679  IPNetwork(const IPNetwork& other)
680  {
681  if (other.m_IPv4Network)
682  {
683  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(*other.m_IPv4Network));
684  }
685 
686  if (other.m_IPv6Network)
687  {
688  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(*other.m_IPv6Network));
689  }
690  }
691 
696  {
697  // NOLINTBEGIN(cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator)
698  if (other.isIPv4Network())
699  {
700  return this->operator=(*other.m_IPv4Network);
701  }
702 
703  return this->operator=(*other.m_IPv6Network);
704  // NOLINTEND(cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator)
705  }
706 
711  {
712  // Create the new instance first to maintain strong exception guarantee.
713  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(other));
714  m_IPv6Network = nullptr;
715  return *this;
716  }
717 
722  {
723  // Create the new instance first to maintain strong exception guarantee.
724  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(other));
725  m_IPv4Network = nullptr;
726  return *this;
727  }
728 
731  uint8_t getPrefixLen() const
732  {
733  return (m_IPv4Network != nullptr ? m_IPv4Network->getPrefixLen() : m_IPv6Network->getPrefixLen());
734  }
735 
738  std::string getNetmask() const
739  {
740  return (m_IPv4Network != nullptr ? m_IPv4Network->getNetmask() : m_IPv6Network->getNetmask());
741  }
742 
746  {
747  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getNetworkPrefix())
748  : IPAddress(m_IPv6Network->getNetworkPrefix()));
749  }
750 
754  {
755  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getLowestAddress())
756  : IPAddress(m_IPv6Network->getLowestAddress()));
757  }
758 
762  {
763  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getHighestAddress())
764  : IPAddress(m_IPv6Network->getHighestAddress()));
765  }
766 
770  uint64_t getTotalAddressCount() const
771  {
772  return (m_IPv4Network != nullptr ? m_IPv4Network->getTotalAddressCount()
773  : m_IPv6Network->getTotalAddressCount());
774  }
775 
777  bool isIPv4Network() const
778  {
779  return m_IPv4Network != nullptr;
780  }
781 
783  bool isIPv6Network() const
784  {
785  return m_IPv6Network != nullptr;
786  }
787 
790  bool includes(const IPAddress& address) const
791  {
792  if (m_IPv4Network != nullptr)
793  {
794  if (address.isIPv6())
795  {
796  return false;
797  }
798 
799  return m_IPv4Network->includes(address.getIPv4());
800  }
801 
802  if (address.isIPv4())
803  {
804  return false;
805  }
806 
807  return m_IPv6Network->includes(address.getIPv6());
808  }
809 
812  bool includes(const IPNetwork& network) const
813  {
814  if (m_IPv4Network != nullptr)
815  {
816  if (network.isIPv6Network())
817  {
818  return false;
819  }
820 
821  return m_IPv4Network->includes(*network.m_IPv4Network);
822  }
823 
824  if (network.isIPv4Network())
825  {
826  return false;
827  }
828 
829  return m_IPv6Network->includes(*network.m_IPv6Network);
830  }
831 
834  std::string toString() const
835  {
836  return (m_IPv4Network != nullptr ? m_IPv4Network->toString() : m_IPv6Network->toString());
837  }
838 
839  private:
840  std::unique_ptr<IPv4Network> m_IPv4Network;
841  std::unique_ptr<IPv6Network> m_IPv6Network;
842  };
843 
844  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv4Address& ipv4Address)
845  {
846  oss << ipv4Address.toString();
847  return oss;
848  }
849 
850  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv6Address& ipv6Address)
851  {
852  oss << ipv6Address.toString();
853  return oss;
854  }
855 
856  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPAddress& ipAddress)
857  {
858  oss << ipAddress.toString();
859  return oss;
860  }
861 
862  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv4Network& network)
863  {
864  oss << network.toString();
865  return oss;
866  }
867 
868  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPv6Network& network)
869  {
870  oss << network.toString();
871  return oss;
872  }
873 
874  inline std::ostream& operator<<(std::ostream& oss, const pcpp::IPNetwork& network)
875  {
876  oss << network.toString();
877  return oss;
878  }
879 } // namespace pcpp
Definition: IpAddress.h:276
IPAddress()
A default constructor that creates an instance of the class with unspecified IPv4 address.
Definition: IpAddress.h:288
std::string toString() const
Definition: IpAddress.h:325
AddressType
An enum representing the address type: IPv4 or IPv6.
Definition: IpAddress.h:280
@ IPv6AddressType
IPv6 address type.
Definition: IpAddress.h:284
@ IPv4AddressType
IPv4 address type.
Definition: IpAddress.h:282
const IPv4Address & getIPv4() const
Definition: IpAddress.h:351
bool operator!=(const IPAddress &rhs) const
Definition: IpAddress.h:382
const IPv6Address & getIPv6() const
Definition: IpAddress.h:358
IPAddress(const std::string &addrAsString)
IPAddress(const IPv4Address &addr)
Definition: IpAddress.h:293
AddressType getType() const
Definition: IpAddress.h:318
bool operator<(const IPAddress &rhs) const
Definition: IpAddress.h:405
bool isIPv4() const
Definition: IpAddress.h:331
bool isZero() const
Definition: IpAddress.h:364
IPAddress & operator=(const IPv4Address &addr)
Definition: IpAddress.h:416
bool isIPv6() const
Definition: IpAddress.h:337
bool isMulticast() const
Definition: IpAddress.h:344
bool operator==(const IPAddress &rhs) const
Definition: IpAddress.h:395
IPAddress(const IPv6Address &addr)
Definition: IpAddress.h:298
Definition: IpAddress.h:609
IPAddress getHighestAddress() const
Definition: IpAddress.h:761
IPNetwork & operator=(const IPv6Network &other)
Definition: IpAddress.h:721
IPAddress getLowestAddress() const
Definition: IpAddress.h:753
bool includes(const IPAddress &address) const
Definition: IpAddress.h:790
bool isIPv6Network() const
Definition: IpAddress.h:783
bool includes(const IPNetwork &network) const
Definition: IpAddress.h:812
std::string toString() const
Definition: IpAddress.h:834
bool isIPv4Network() const
Definition: IpAddress.h:777
IPNetwork & operator=(const IPNetwork &other)
Definition: IpAddress.h:695
IPNetwork(const IPNetwork &other)
Definition: IpAddress.h:679
IPAddress getNetworkPrefix() const
Definition: IpAddress.h:745
IPNetwork(const IPAddress &address, const std::string &netmask)
Definition: IpAddress.h:645
uint64_t getTotalAddressCount() const
Definition: IpAddress.h:770
std::string getNetmask() const
Definition: IpAddress.h:738
uint8_t getPrefixLen() const
Definition: IpAddress.h:731
IPNetwork & operator=(const IPv4Network &other)
Definition: IpAddress.h:710
IPNetwork(const IPAddress &address)
Definition: IpAddress.h:614
IPNetwork(const std::string &addressAndNetmask)
Definition: IpAddress.h:665
IPNetwork(const IPAddress &address, uint8_t prefixLen)
Definition: IpAddress.h:624
Definition: IpAddress.h:28
static bool isValidIPv4Address(const std::string &addrAsString)
bool matchNetwork(const std::string &network) const
static const IPv4Address MulticastRangeLowerBound
Definition: IpAddress.h:137
IPv4Address(const std::array< uint8_t, 4 > &bytes)
Definition: IpAddress.h:49
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:61
bool operator!=(const IPv4Address &rhs) const
Definition: IpAddress.h:104
IPv4Address(const uint32_t addrAsInt)
Definition: IpAddress.h:35
IPv4Address(const uint8_t bytes[4])
Definition: IpAddress.h:42
bool operator==(const IPv4Address &rhs) const
Definition: IpAddress.h:81
bool operator<(const IPv4Address &rhs) const
Definition: IpAddress.h:89
const std::array< uint8_t, 4 > & toByteArray() const
Definition: IpAddress.h:67
uint32_t toInt() const
Definition: IpAddress.h:146
static const IPv4Address Zero
A static value representing a zero value of IPv4 address, meaning address of value "0....
Definition: IpAddress.h:131
bool isMulticast() const
Definition: IpAddress.h:433
IPv4Network(const IPv4Address &address)
Definition: IpAddress.h:438
IPv4Address getLowestAddress() const
std::string getNetmask() const
Definition: IpAddress.h:473
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:479
IPv4Network(const std::string &addressAndNetmask)
bool includes(const IPv4Network &network) const
Definition: IpAddress.h:156
static const IPv6Address MulticastRangeLowerBound
Definition: IpAddress.h:267
void copyTo(uint8_t *arr) const
Definition: IpAddress.h:232
void copyTo(uint8_t **arr, size_t &length) const
const uint8_t * toBytes() const
Definition: IpAddress.h:180
bool matchNetwork(const IPv6Network &network) const
IPv6Address(const uint8_t bytes[16])
Definition: IpAddress.h:163
static const IPv6Address Zero
Definition: IpAddress.h:262
bool matchNetwork(const std::string &network) const
bool operator<(const IPv6Address &rhs) const
Definition: IpAddress.h:211
bool operator!=(const IPv6Address &rhs) const
Definition: IpAddress.h:219
const std::array< uint8_t, 16 > & toByteArray() const
Definition: IpAddress.h:187
IPv6Address(const std::string &addrAsString)
bool isMulticast() const
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:203
IPv6Address(const std::array< uint8_t, 16 > &bytes)
Definition: IpAddress.h:170
Definition: IpAddress.h:521
IPv6Network(const std::string &addressAndNetmask)
IPv6Address getHighestAddress() const
uint8_t getPrefixLen() const
std::string getNetmask() const
Definition: IpAddress.h:561
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:567
std::string toString() const
bool includes(const IPv6Address &address) const
IPv6Network(const IPv6Address &address)
Definition: IpAddress.h:526
The main namespace for the PcapPlusPlus lib.