PcapPlusPlus  Next
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 
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;
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:
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  return rhs.isIPv4() ? (m_IPv4 == rhs.m_IPv4) : false;
399 
400  return rhs.isIPv6() ? m_IPv6 == rhs.m_IPv6 : false;
401  }
402 
403  bool IPAddress::operator<(const IPAddress& rhs) const
404  {
405  if (isIPv4())
406  {
407  // treat IPv4 as less than IPv6
408  // If current obj is IPv4 and other is IPv6 return true
409  return rhs.isIPv4() ? (m_IPv4 < rhs.m_IPv4) : true;
410  }
411  return rhs.isIPv6() ? m_IPv6 < rhs.m_IPv6 : false;
412  }
413 
415  {
416  m_Type = IPv4AddressType;
417  m_IPv4 = addr;
418  return *this;
419  }
420 
422  {
423  m_Type = IPv6AddressType;
424  m_IPv6 = addr;
425  return *this;
426  }
427 
431  {
432  public:
436  explicit IPv4Network(const IPv4Address& address) : IPv4Network(address, 32u)
437  {}
438 
445  IPv4Network(const IPv4Address& address, uint8_t prefixLen);
446 
455  IPv4Network(const IPv4Address& address, const std::string& netmask);
456 
465  IPv4Network(const std::string& addressAndNetmask);
466 
468  uint8_t getPrefixLen() const;
469 
471  std::string getNetmask() const
472  {
473  return IPv4Address(m_Mask).toString();
474  }
475 
478  {
479  return IPv4Address(m_NetworkPrefix);
480  }
481 
485 
489 
492  uint64_t getTotalAddressCount() const;
493 
496  bool includes(const IPv4Address& address) const;
497 
501  bool includes(const IPv4Network& network) const;
502 
505  std::string toString() const;
506 
507  private:
508  uint32_t m_NetworkPrefix;
509  uint32_t m_Mask;
510 
511  bool isValidNetmask(const IPv4Address& netmaskAddress);
512  void initFromAddressAndPrefixLength(const IPv4Address& address, uint8_t prefixLen);
513  void initFromAddressAndNetmask(const IPv4Address& address, const IPv4Address& netmaskAddress);
514  };
515 
519  {
520  public:
524  explicit IPv6Network(const IPv6Address& address) : IPv6Network(address, 128u)
525  {}
526 
533  IPv6Network(const IPv6Address& address, uint8_t prefixLen);
534 
543  IPv6Network(const IPv6Address& address, const std::string& netmask);
544 
553  IPv6Network(const std::string& addressAndNetmask);
554 
556  uint8_t getPrefixLen() const;
557 
559  std::string getNetmask() const
560  {
561  return IPv6Address(m_Mask).toString();
562  }
563 
566  {
567  return IPv6Address(m_NetworkPrefix);
568  }
569 
573 
577 
580  uint64_t getTotalAddressCount() const;
581 
584  bool includes(const IPv6Address& address) const;
585 
589  bool includes(const IPv6Network& network) const;
590 
593  std::string toString() const;
594 
595  private:
596  uint8_t m_NetworkPrefix[16];
597  uint8_t m_Mask[16];
598 
599  bool isValidNetmask(const IPv6Address& netmaskAddress);
600  void initFromAddressAndPrefixLength(const IPv6Address& address, uint8_t prefixLen);
601  void initFromAddressAndNetmask(const IPv6Address& address, const IPv6Address& netmaskAddress);
602  };
603 
606  class IPNetwork
607  {
608  public:
612  explicit IPNetwork(const IPAddress& address) : IPNetwork(address, address.isIPv4() ? 32u : 128u)
613  {}
614 
622  IPNetwork(const IPAddress& address, uint8_t prefixLen)
623  {
624  if (address.isIPv4())
625  {
626  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), prefixLen));
627  }
628  else
629  {
630  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), prefixLen));
631  }
632  }
633 
643  IPNetwork(const IPAddress& address, const std::string& netmask)
644  {
645  if (address.isIPv4())
646  {
647  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(address.getIPv4(), netmask));
648  }
649  else
650  {
651  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(address.getIPv6(), netmask));
652  }
653  }
654 
663  IPNetwork(const std::string& addressAndNetmask)
664  {
665  try
666  {
667  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(addressAndNetmask));
668  }
669  catch (const std::invalid_argument&)
670  {
671  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(addressAndNetmask));
672  }
673  }
674 
677  IPNetwork(const IPNetwork& other)
678  {
679  if (other.m_IPv4Network)
680  {
681  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(*other.m_IPv4Network));
682  }
683 
684  if (other.m_IPv6Network)
685  {
686  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(*other.m_IPv6Network));
687  }
688  }
689 
694  {
695  if (other.isIPv4Network())
696  {
697  return this->operator=(*other.m_IPv4Network);
698  }
699  else
700  {
701  return this->operator=(*other.m_IPv6Network);
702  }
703  }
704 
709  {
710  // Create the new instance first to maintain strong exception guarantee.
711  m_IPv4Network = std::unique_ptr<IPv4Network>(new IPv4Network(other));
712  m_IPv6Network = nullptr;
713  return *this;
714  }
715 
720  {
721  // Create the new instance first to maintain strong exception guarantee.
722  m_IPv6Network = std::unique_ptr<IPv6Network>(new IPv6Network(other));
723  m_IPv4Network = nullptr;
724  return *this;
725  }
726 
729  uint8_t getPrefixLen() const
730  {
731  return (m_IPv4Network != nullptr ? m_IPv4Network->getPrefixLen() : m_IPv6Network->getPrefixLen());
732  }
733 
736  std::string getNetmask() const
737  {
738  return (m_IPv4Network != nullptr ? m_IPv4Network->getNetmask() : m_IPv6Network->getNetmask());
739  }
740 
744  {
745  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getNetworkPrefix())
746  : IPAddress(m_IPv6Network->getNetworkPrefix()));
747  }
748 
752  {
753  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getLowestAddress())
754  : IPAddress(m_IPv6Network->getLowestAddress()));
755  }
756 
760  {
761  return (m_IPv4Network != nullptr ? IPAddress(m_IPv4Network->getHighestAddress())
762  : IPAddress(m_IPv6Network->getHighestAddress()));
763  }
764 
768  uint64_t getTotalAddressCount() const
769  {
770  return (m_IPv4Network != nullptr ? m_IPv4Network->getTotalAddressCount()
771  : m_IPv6Network->getTotalAddressCount());
772  }
773 
775  bool isIPv4Network() const
776  {
777  return m_IPv4Network != nullptr;
778  }
779 
781  bool isIPv6Network() const
782  {
783  return m_IPv6Network != nullptr;
784  }
785 
788  bool includes(const IPAddress& address) const
789  {
790  if (m_IPv4Network != nullptr)
791  {
792  if (address.isIPv6())
793  {
794  return false;
795  }
796 
797  return m_IPv4Network->includes(address.getIPv4());
798  }
799  else
800  {
801  if (address.isIPv4())
802  {
803  return false;
804  }
805 
806  return m_IPv6Network->includes(address.getIPv6());
807  }
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  else
824  {
825  if (network.isIPv4Network())
826  {
827  return false;
828  }
829 
830  return m_IPv6Network->includes(*network.m_IPv6Network);
831  }
832  }
833 
836  std::string toString() const
837  {
838  return (m_IPv4Network != nullptr ? m_IPv4Network->toString() : m_IPv6Network->toString());
839  }
840 
841  private:
842  std::unique_ptr<IPv4Network> m_IPv4Network;
843  std::unique_ptr<IPv6Network> m_IPv6Network;
844  };
845 
846  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv4Address& ipv4Address)
847  {
848  os << ipv4Address.toString();
849  return os;
850  }
851 
852  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv6Address& ipv6Address)
853  {
854  os << ipv6Address.toString();
855  return os;
856  }
857 
858  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPAddress& ipAddress)
859  {
860  os << ipAddress.toString();
861  return os;
862  }
863 
864  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv4Network& network)
865  {
866  os << network.toString();
867  return os;
868  }
869 
870  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPv6Network& network)
871  {
872  os << network.toString();
873  return os;
874  }
875 
876  inline std::ostream& operator<<(std::ostream& os, const pcpp::IPNetwork& network)
877  {
878  os << network.toString();
879  return os;
880  }
881 
882 } // 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
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:403
bool isIPv4() const
Definition: IpAddress.h:331
bool isZero() const
Definition: IpAddress.h:364
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
IPAddress & operator=(const IPv4Address &addr)
Definition: IpAddress.h:414
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:607
IPAddress getHighestAddress() const
Definition: IpAddress.h:759
IPNetwork & operator=(const IPv6Network &other)
Definition: IpAddress.h:719
IPAddress getLowestAddress() const
Definition: IpAddress.h:751
bool includes(const IPAddress &address) const
Definition: IpAddress.h:788
bool isIPv6Network() const
Definition: IpAddress.h:781
bool includes(const IPNetwork &network) const
Definition: IpAddress.h:812
std::string toString() const
Definition: IpAddress.h:836
bool isIPv4Network() const
Definition: IpAddress.h:775
IPNetwork & operator=(const IPNetwork &other)
Definition: IpAddress.h:693
IPNetwork(const IPNetwork &other)
Definition: IpAddress.h:677
IPAddress getNetworkPrefix() const
Definition: IpAddress.h:743
IPNetwork(const IPAddress &address, const std::string &netmask)
Definition: IpAddress.h:643
uint64_t getTotalAddressCount() const
Definition: IpAddress.h:768
std::string getNetmask() const
Definition: IpAddress.h:736
uint8_t getPrefixLen() const
Definition: IpAddress.h:729
IPNetwork & operator=(const IPv4Network &other)
Definition: IpAddress.h:708
IPNetwork(const IPAddress &address)
Definition: IpAddress.h:612
IPNetwork(const std::string &addressAndNetmask)
Definition: IpAddress.h:663
IPNetwork(const IPAddress &address, uint8_t prefixLen)
Definition: IpAddress.h:622
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:431
IPv4Network(const IPv4Address &address)
Definition: IpAddress.h:436
IPv4Address getLowestAddress() const
std::string getNetmask() const
Definition: IpAddress.h:471
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:477
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:519
IPv6Network(const std::string &addressAndNetmask)
IPv6Address getHighestAddress() const
uint8_t getPrefixLen() const
std::string getNetmask() const
Definition: IpAddress.h:559
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:565
std::string toString() const
bool includes(const IPv6Address &address) const
IPv6Network(const IPv6Address &address)
Definition: IpAddress.h:524
The main namespace for the PcapPlusPlus lib.