EpcTools
An event based multi-threaded C++ development framework.
eip.h
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2020 Sprint
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #ifndef __eip_h_included
18 #define __eip_h_included
19 
20 #include <arpa/inet.h>
21 #include <netinet/in.h>
22 #include <list>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "epctools.h"
27 #include "ehash.h"
28 
31 
33 DECLARE_ERROR_ADVANCED2(EIpAddress_UnrecognizedAddressFamily);
34 inline EIpAddress_UnrecognizedAddressFamily::EIpAddress_UnrecognizedAddressFamily(Int af) {
35  setTextf("Unrecognized address family %d", af);
36 }
38 
41 {
42 public:
45  : family_(AF_UNSPEC)
46  {
47  memset(&address_, 0, sizeof(address_));
48  }
51  EIpAddress(cpStr addr)
52  : family_(AF_UNSPEC)
53  {
54  *this = addr;
55  }
58  EIpAddress(const std::string &addr)
59  : family_(AF_UNSPEC)
60  {
61  *this = addr.c_str();
62  }
65  EIpAddress(const EIpAddress &ipaddr)
66  : family_(AF_UNSPEC)
67  {
68  *this = ipaddr;
69  }
72  EIpAddress(const struct sockaddr_storage &saddr)
73  : family_(AF_UNSPEC)
74  {
75  *this = saddr;
76  }
77 
80  EIpAddress &operator=(cpStr addr)
81  {
82  auto parts = EUtility::split(addr, "/");
83  memset(&address_, 0, sizeof(address_));
84  if (inet_pton(AF_INET, parts[0], &address_.ipv4) == 1)
85  {
86  if (family_ != AF_INET)
87  family_ = AF_INET;
88  maskWidth_ = (parts.size() > 1) ? static_cast<UChar>(std::stoi(parts[1])) : 32;
89  }
90  else if (inet_pton(AF_INET6, parts[0], &address_.ipv6) == 1)
91  {
92  if (family_ != AF_INET6)
93  family_ = AF_INET6;
94  maskWidth_ = (parts.size() > 1) ? static_cast<UChar>(std::stoi(parts[1])) : 128;
95  }
96  else
97  {
98  family_ = AF_UNSPEC;
99  maskWidth_ = 0;
100  }
101 
102  return *this;
103  }
104 
108  {
109  family_ = ipaddr.family_;
110  maskWidth_ = ipaddr.maskWidth_;
111  memset(&address_, 0, sizeof(address_));
112  switch (family_)
113  {
114  case AF_INET: { address_.ipv4.s_addr = ipaddr.address_.ipv4.s_addr; break; }
115  case AF_INET6: { memcpy(address_.ipv6.s6_addr, ipaddr.address_.ipv6.s6_addr, sizeof(address_.ipv6.s6_addr)); break; }
116  default: { break; }
117  }
118  return *this;
119  }
120 
123  EIpAddress &operator=(const struct sockaddr_storage &saddr)
124  {
125  switch (saddr.ss_family)
126  {
127  case AF_INET: { return EIpAddress::operator=(((const struct sockaddr_in&)saddr).sin_addr); }
128  case AF_INET6: { return EIpAddress::operator=(((const struct sockaddr_in6&)saddr).sin6_addr); }
129  default:
130  {
131  throw EIpAddress_UnrecognizedAddressFamily(saddr.ss_family);
132  }
133  }
134  return *this;
135  }
136 
139  EIpAddress &operator=(const in_addr &addr)
140  {
141  if (family_ != AF_INET)
142  {
143  family_ = AF_INET;
144  maskWidth_ = 32;
145  }
146  address_.ipv4.s_addr = addr.s_addr;
147  return *this;
148  }
149 
152  EIpAddress &operator=(const in6_addr &addr)
153  {
154  if (family_ != AF_INET6)
155  {
156  family_ = AF_INET6;
157  maskWidth_ = 128;
158  }
159  memcpy(address_.ipv6.s6_addr, addr.s6_addr, sizeof(address_.ipv6.s6_addr));
160  return *this;
161  }
162 
165  Bool operator==(const EIpAddress &ip) const
166  {
167  return
168  family_ == ip.family_ &&
169  maskWidth_ == ip.maskWidth_ &&
170  (
171  (family_ == AF_INET && address_.ipv4.s_addr == ip.address_.ipv4.s_addr) ||
172  (
173  family_ == AF_INET6 &&
174  address_.ipv6.s6_addr[0] == ip.address_.ipv6.s6_addr[0] &&
175  address_.ipv6.s6_addr[1] == ip.address_.ipv6.s6_addr[1] &&
176  address_.ipv6.s6_addr[2] == ip.address_.ipv6.s6_addr[2] &&
177  address_.ipv6.s6_addr[3] == ip.address_.ipv6.s6_addr[3] &&
178  address_.ipv6.s6_addr[4] == ip.address_.ipv6.s6_addr[4] &&
179  address_.ipv6.s6_addr[5] == ip.address_.ipv6.s6_addr[5] &&
180  address_.ipv6.s6_addr[6] == ip.address_.ipv6.s6_addr[6] &&
181  address_.ipv6.s6_addr[7] == ip.address_.ipv6.s6_addr[7] &&
182  address_.ipv6.s6_addr[8] == ip.address_.ipv6.s6_addr[8] &&
183  address_.ipv6.s6_addr[9] == ip.address_.ipv6.s6_addr[9] &&
184  address_.ipv6.s6_addr[10] == ip.address_.ipv6.s6_addr[10] &&
185  address_.ipv6.s6_addr[11] == ip.address_.ipv6.s6_addr[11] &&
186  address_.ipv6.s6_addr[12] == ip.address_.ipv6.s6_addr[12] &&
187  address_.ipv6.s6_addr[13] == ip.address_.ipv6.s6_addr[13] &&
188  address_.ipv6.s6_addr[14] == ip.address_.ipv6.s6_addr[14] &&
189  address_.ipv6.s6_addr[15] == ip.address_.ipv6.s6_addr[15]
190  )
191  )
192  ;
193  }
194 
198  std::string address(Bool includeMask = True) const
199  {
200  if (isAny())
201  {
202  std::string str = "any";
203  return str;
204  }
205 
206  Char buf[INET6_ADDRSTRLEN] = {};
207 
208  switch (family_)
209  {
210  case AF_INET: { inet_ntop(AF_INET,&address_.ipv4,buf,sizeof(buf)); break; }
211  case AF_INET6: { inet_ntop(AF_INET6,&address_.ipv6,buf,sizeof(buf)); break; }
212  default: { break; }
213  }
214 
215  std::stringstream ss;
216  ss << buf;
217  if (includeMask)
218  ss << "/" << static_cast<Int>(maskWidth());
219 
220  return ss.str();
221  }
222 
225  const in_addr &ipv4Address() const { return address_.ipv4; }
228  const in6_addr &ipv6Address() const { return address_.ipv6; }
231  const sa_family_t family() const { return family_; }
234  UChar maskWidth() const { return maskWidth_; }
235 
239  EIpAddress &setFamily(const sa_family_t family)
240  {
241  family_ = family;
242  return *this;
243  }
248  {
249  switch (family_)
250  {
251  case AF_INET: { maskWidth_ = (maskWidth > 32) ? 32 : maskWidth; break; }
252  case AF_INET6: { maskWidth_ = (maskWidth > 128) ? 128 : maskWidth; break; }
253  default: { break; }
254  }
255  return *this;
256  }
257 
261  EIpAddress &setAny(sa_family_t family)
262  {
263  setFamily(family);
264  memset(&address_,0,sizeof(address_));
265  maskWidth_ = 0;
266  return *this;
267  }
268 
271  Bool isAny() const
272  {
273  if (maskWidth_ != 0)
274  return False;
275  switch (family_)
276  {
277  case AF_INET: { if (address_.ipv4.s_addr == 0) return True; break; }
278  case AF_INET6: { for (auto b : address_.ipv6.s6_addr) { if (b != 0) return False; } return True; }
279  default: { break; }
280  }
281  return False;
282  }
283 
284 private:
285  sa_family_t family_;
286  union {
287  in_addr ipv4;
288  in6_addr ipv6;
289  } address_;
290  UChar maskWidth_;
291 };
292 
293 namespace std
294 {
296 template <>
297 struct hash<EIpAddress>
298 {
299  std::size_t operator()(const EIpAddress &addr) const noexcept
300  {
301  size_t iphash = 0xc70f6907UL;
302  switch (addr.family())
303  {
304  case AF_INET: { iphash = EMurmurHash64::getHash(reinterpret_cast<cpUChar>(&addr.ipv4Address()), sizeof(in_addr)); break; }
305  case AF_INET6: { iphash = EMurmurHash64::getHash(reinterpret_cast<cpUChar>(&addr.ipv6Address()), sizeof(in6_addr)); break; }
306  default: { break; }
307  }
308  size_t mwhash = std::hash<UChar>{}(addr.maskWidth());
309  return EMurmurHash64::combine(iphash, mwhash);
310  }
311 };
312 } // namespace std
313 
314 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidAction);
315 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidDirection);
316 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidProtocol);
317 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidIpAddress);
318 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidMaskWidth);
319 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidPort);
320 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidOption);
321 DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidOptionMissingSpec);
322 
325 {
326 public:
327  enum class Action
328  {
329  Undefined,
330  Permit,
331  Deny
332  };
333  enum class Direction
334  {
335  Undefined,
336  In,
337  Out
338  };
339  enum class OptionType
340  {
341  Undefined,
342  frag,
343  ipoptions,
344  tcpoptions,
345  established,
346  setup,
347  tcpflags,
348  icmptypes
349  };
350  enum class Protocol
351  {
352  Undefined = -1,
353  ProtoMin = 0,
354  IP = 0, /* dummy for IP */
355  HOPOPTS = 0, /* IP6 hop-by-hop options */
356  ICMP = 1, /* control message protocol */
357  IGMP = 2, /* group mgmt protocol */
358  GGP = 3, /* gateway^2 (deprecated) */
359  IPV4 = 4, /* IPv4 encapsulation */
360  IPIP = 4, /* for compatibility */
361  TCP = 6, /* tcp */
362  ST = 7, /* Stream protocol II */
363  EGP = 8, /* exterior gateway protocol */
364  PIGP = 9, /* private interior gateway */
365  RCCMON = 10, /* BBN RCC Monitoring */
366  NVPII = 11, /* network voice protocol*/
367  PUP = 12, /* pup */
368  ARGUS = 13, /* Argus */
369  EMCON = 14, /* EMCON */
370  XNET = 15, /* Cross Net Debugger */
371  CHAOS = 16, /* Chaos*/
372  UDP = 17, /* user datagram protocol */
373  MUX = 18, /* Multiplexing */
374  MEAS = 19, /* DCN Measurement Subsystems */
375  HMP = 20, /* Host Monitoring */
376  PRM = 21, /* Packet Radio Measurement */
377  IDP = 22, /* xns idp */
378  TRUNK1 = 23, /* Trunk-1 */
379  TRUNK2 = 24, /* Trunk-2 */
380  LEAF1 = 25, /* Leaf-1 */
381  LEAF2 = 26, /* Leaf-2 */
382  RDP = 27, /* Reliable Data */
383  IRTP = 28, /* Reliable Transaction */
384  TP = 29, /* tp-4 w/ class negotiation */
385  BLT = 30, /* Bulk Data Transfer */
386  NSP = 31, /* Network Services */
387  INP = 32, /* Merit Internodal */
388  SEP = 33, /* Sequential Exchange */
389  TPC = 34, /* Third Party Connect */
390  IDPR = 35, /* InterDomain Policy Routing */
391  XTP = 36, /* XTP */
392  DDP = 37, /* Datagram Delivery */
393  CMTP = 38, /* Control Message Transport */
394  TPXX = 39, /* TP++ Transport */
395  IL = 40, /* IL transport protocol */
396  IPV6 = 41, /* IP6 header */
397  SDRP = 42, /* Source Demand Routing */
398  ROUTING = 43, /* IP6 routing header */
399  FRAGMENT = 44, /* IP6 fragmentation header */
400  IDRP = 45, /* InterDomain Routing*/
401  RSVP = 46, /* resource reservation */
402  GRE = 47, /* General Routing Encap. */
403  MHRP = 48, /* Mobile Host Routing */
404  BHA = 49, /* BHA */
405  ESP = 50, /* IP6 Encap Sec. Payload */
406  AH = 51, /* IP6 Auth Header */
407  INLSP = 52, /* Integ. Net Layer Security */
408  SWIPE = 53, /* IP with encryption */
409  NHRP = 54, /* Next Hop Resolution */
410  ICMPV6 = 58, /* ICMP6 */
411  NONE = 59, /* IP6 no next header */
412  DSTOPTS = 60, /* IP6 destination option */
413  AHIP = 61, /* any host internal protocol */
414  CFTP = 62, /* CFTP */
415  HELLO = 63, /* "hello" routing protocol */
416  SATEXPAK = 64, /* SATNET/Backroom EXPAK */
417  KRYPTOLAN = 65, /* Kryptolan */
418  RVD = 66, /* Remote Virtual Disk */
419  IPPC = 67, /* Pluribus Packet Core */
420  ADFS = 68, /* Any distributed FS */
421  SATMON = 69, /* Satnet Monitoring */
422  VISA = 70, /* VISA Protocol */
423  IPCV = 71, /* Packet Core Utility */
424  CPNX = 72, /* Comp. Prot. Net. Executive */
425  CPHB = 73, /* Comp. Prot. HeartBeat */
426  WSN = 74, /* Wang Span Network */
427  PVP = 75, /* Packet Video Protocol */
428  BRSATMON = 76, /* BackRoom SATNET Monitoring */
429  ND = 77, /* Sun net disk proto (temp.) */
430  WBMON = 78, /* WIDEBAND Monitoring */
431  WBEXPAK = 79, /* WIDEBAND EXPAK */
432  EON = 80, /* ISO cnlp */
433  VMTP = 81, /* VMTP */
434  SVMTP = 82, /* Secure VMTP */
435  VINES = 83, /* Banyon VINES */
436  TTP = 84, /* TTP */
437  IGP = 85, /* NSFNET-IGP */
438  DGP = 86, /* dissimilar gateway prot. */
439  TCF = 87, /* TCF */
440  IGRP = 88, /* Cisco/GXS IGRP */
441  OSPFIGP = 89, /* OSPFIGP */
442  SRPC = 90, /* Strite RPC protocol */
443  LARP = 91, /* Locus Address Resoloution */
444  MTP = 92, /* Multicast Transport */
445  AX25 = 93, /* AX.25 Frames */
446  IPEIP = 94, /* IP encapsulated in IP */
447  MICP = 95, /* Mobile Int.ing control */
448  SCCSP = 96, /* Semaphore Comm. security */
449  ETHERIP = 97, /* Ethernet IP encapsulation */
450  ENCAP = 98, /* encapsulation header */
451  APES = 99, /* any private encr. scheme */
452  GMTP = 100, /* GMTP*/
453  PIM = 103, /* Protocol Independent Mcast */
454  IPCOMP = 108, /* payload compression (IPComp) */
455  PGM = 113, /* PGM */
456  SCTP = 132, /* SCTP */
457  DIVERT = 254, /* divert pseudo-protocol */
458  RAW = 255, /* raw IP packet */
459  ProtoMax = 255
460  };
461 
463  class Port
464  {
465  public:
469  Port(UShort first = 0, UShort last = 0) : first_(first), last_(!last ? first : last) {}
472  Port(const Port &p) : first_(p.first_), last_(p.last_) {}
473 
476  UShort first() const { return first_; }
479  UShort last() const { return last_; }
480 
484  Port &setFirst(UShort first)
485  {
486  first_ = first;
487  if (first_ > last_)
488  last_ = first_;
489  return *this;
490  }
494  Port &setLast(UShort last)
495  {
496  last_ = last;
497  if (first_ > last_)
498  first_ = last_;
499  return *this;
500  }
505  Port &setFirstLast(UShort first, UShort last)
506  {
507  setLast(last).setFirst(first);
508  return *this;
509  }
510 
511  private:
512  UShort first_;
513  UShort last_;
514  };
515  typedef std::vector<Port> PortVec;
516 
518  class Option
519  {
520  public:
521  Option() : type_(OptionType::Undefined) {}
522  Option(OptionType t) : type_(t) {}
523  Option(const Option &o) : type_(o.type_) {}
524  virtual ~Option() {}
525  OptionType type() const { return type_; }
527  {
528  type_ = t;
529  return *this;
530  }
531  virtual size_t hash() const = 0;
532 
533  private:
534  OptionType type_;
535  };
536  typedef std::shared_ptr<Option> OptionPtr;
537  typedef std::vector<OptionPtr> OptionPtrVec;
538 
540  class Fragment : public Option
541  {
542  public:
543  Fragment() : Option(OptionType::frag) {}
544  virtual ~Fragment() {}
545 
546  size_t hash() const
547  {
548  return std::hash<Int>{}(static_cast<Int>(type()));
549  }
550  };
551 
553  class IpOptions : public Option
554  {
555  public:
556  IpOptions() : Option(OptionType::ipoptions) {}
557  IpOptions(cpChar spec) : Option(OptionType::ipoptions), spec_(spec) {}
558  IpOptions(const IpOptions &o) : Option(OptionType::ipoptions), spec_(o.spec_) {}
559  virtual ~IpOptions() {}
560  const EString &spec() { return spec_; }
561  IpOptions &setSpec(cpChar spec)
562  {
563  spec_ = spec;
564  return *this;
565  }
566  IpOptions &setSpec(const EString &spec)
567  {
568  spec_ = spec;
569  return *this;
570  }
571  IpOptions &setSpec(const std::string &spec)
572  {
573  spec_ = spec;
574  return *this;
575  }
576 
577  size_t hash() const
578  {
579  size_t typehash = std::hash<Int>{}(static_cast<Int>(type()));
580  size_t spechash = std::hash<std::string>{}(spec_);
581  return EMurmurHash64::combine(typehash, spechash);
582  }
583 
584  private:
585  EString spec_;
586  };
587 
589  class TcpOptions : public Option
590  {
591  public:
592  TcpOptions() : Option(OptionType::tcpoptions) {}
593  TcpOptions(cpChar spec) : Option(OptionType::tcpoptions), spec_(spec) {}
594  TcpOptions(const TcpOptions &o) : Option(OptionType::tcpoptions), spec_(o.spec_) {}
595  virtual ~TcpOptions() {}
596  const EString &spec() { return spec_; }
597  TcpOptions &setSpec(cpChar spec)
598  {
599  spec_ = spec;
600  return *this;
601  }
602  TcpOptions &setSpec(const EString &spec)
603  {
604  spec_ = spec;
605  return *this;
606  }
607  TcpOptions &setSpec(const std::string &spec)
608  {
609  spec_ = spec;
610  return *this;
611  }
612 
613  size_t hash() const
614  {
615  size_t typehash = std::hash<Int>{}(static_cast<Int>(type()));
616  size_t spechash = std::hash<std::string>{}(spec_);
617  return EMurmurHash64::combine(typehash, spechash);
618  }
619 
620  private:
621  EString spec_;
622  };
623 
625  class Established : public Option
626  {
627  public:
628  Established() : Option(OptionType::established) {}
629  virtual ~Established() {}
630  size_t hash() const
631  {
632  return std::hash<Int>{}(static_cast<Int>(type()));
633  }
634  };
635 
637  class Setup : public Option
638  {
639  public:
640  Setup() : Option(OptionType::setup) {}
641  virtual ~Setup() {}
642  size_t hash() const
643  {
644  return std::hash<Int>{}(static_cast<Int>(type()));
645  }
646  };
647 
649  class TcpFlags : public Option
650  {
651  public:
652  TcpFlags() : Option(OptionType::tcpflags) {}
653  TcpFlags(cpChar flags) : Option(OptionType::tcpflags), flags_(flags) {}
654  TcpFlags(const TcpFlags &o) : Option(OptionType::tcpflags), flags_(o.flags_) {}
655  virtual ~TcpFlags() {}
656  const EString &flags() { return flags_; }
657  TcpFlags &setFlags(cpChar flags)
658  {
659  flags_ = flags;
660  return *this;
661  }
662  TcpFlags &setFlags(const EString &flags)
663  {
664  flags_ = flags;
665  return *this;
666  }
667  TcpFlags &setFlags(const std::string &flags)
668  {
669  flags_ = flags;
670  return *this;
671  }
672  size_t hash() const
673  {
674  size_t typehash = std::hash<Int>{}(static_cast<Int>(type()));
675  size_t flagshash = std::hash<std::string>{}(flags_);
676  return EMurmurHash64::combine(typehash, flagshash);
677  }
678 
679  private:
680  EString flags_;
681  };
682 
684  class IcmpTypes : public Option
685  {
686  public:
687  IcmpTypes() : Option(OptionType::icmptypes) {}
688  IcmpTypes(cpChar types) : Option(OptionType::icmptypes), types_(types) {}
689  IcmpTypes(const IcmpTypes &o) : Option(OptionType::icmptypes), types_(o.types_) {}
690  virtual ~IcmpTypes() {}
691  const EString &types() { return types_; }
692  IcmpTypes &setTypes(cpChar types)
693  {
694  types_ = types;
695  return *this;
696  }
697  IcmpTypes &setTypes(const EString &types)
698  {
699  types_ = types;
700  return *this;
701  }
702  IcmpTypes &setTypes(const std::string &types)
703  {
704  types_ = types;
705  return *this;
706  }
707  size_t hash() const
708  {
709  size_t typehash = std::hash<Int>{}(static_cast<Int>(type()));
710  size_t typeshash = std::hash<std::string>{}(types_);
711  return EMurmurHash64::combine(typehash, typeshash);
712  }
713 
714  private:
715  EString types_;
716  };
717 
719  EIpFilterRule() : action_(Action::Undefined), dir_(Direction::Undefined), proto_(Protocol::Undefined) {}
722  EIpFilterRule(cpChar raw) : action_(Action::Undefined), dir_(Direction::Undefined), proto_(Protocol::Undefined) { parse(raw); }
726  : orig_(r.original()),
727  action_(r.action()),
728  dir_(r.direction()),
729  proto_(r.protocol()),
730  src_(r.source()),
731  srcPorts_(r.sourcePorts()),
732  dst_(r.destination()),
733  dstPorts_(r.destinationPorts()),
734  options_(options())
735  {
736  }
737 
741  {
742  orig_ = r.orig_;
743  action_ = r.action_;
744  dir_ = r.dir_;
745  src_ = r.src_;
746  srcPorts_ = r.srcPorts_;
747  dst_ = r.dst_;
748  dstPorts_ = r.dstPorts_;
749  options_ = r.options_;
750  return *this;
751  }
752 
755  EIpFilterRule &operator=(const std::string &r) { return parse(r); }
758  EIpFilterRule &operator=(cpStr r) { return parse(r); }
759 
761  const EString &original() const { return orig_; }
763  const Action action() const { return action_; }
765  const Direction direction() const { return dir_; }
767  const Protocol protocol() const { return proto_; }
769  const EIpAddress &source() const { return src_; }
771  const PortVec &sourcePorts() const { return srcPorts_; }
773  const EIpAddress &destination() const { return dst_; }
775  const PortVec &destinationPorts() const { return dstPorts_; }
777  const OptionPtrVec &options() const { return options_; }
778 
784  {
785  orig_ = orig;
786  return *this;
787  }
789  {
790  orig_ = orig;
791  return *this;
792  }
793  EIpFilterRule &setOriginal(const std::string &orig)
794  {
795  orig_ = orig;
796  return *this;
797  }
799 
804  {
805  action_ = action;
806  return *this;
807  }
812  {
813  dir_ = dir;
814  return *this;
815  }
820  {
821  proto_ = proto;
822  return *this;
823  }
828  {
829  src_ = src;
830  return *this;
831  }
836  {
837  dst_ = dst;
838  return *this;
839  }
844  EIpFilterRule &addSourcePort(UShort first = 0, UShort last = 0)
845  {
846  srcPorts_.push_back(Port(first, last));
847  return *this;
848  }
853  {
854  srcPorts_.push_back(p);
855  return *this;
856  }
861  EIpFilterRule &addDestinationPort(UShort first = 0, UShort last = 0)
862  {
863  dstPorts_.push_back(Port(first, last));
864  return *this;
865  }
870  {
871  dstPorts_.push_back(p);
872  return *this;
873  }
877  EIpFilterRule &parse(cpChar raw) { return parse(std::string(raw)); }
881  EIpFilterRule &parse(const std::string &raw);
884  Void dump(cpStr padding="");
887  EString final();
888 
889 private:
890  Action parseAction(const EString &str);
891  Direction parseDirection(const EString &str);
892  Protocol parseProtocol(const EString &str);
893  EIpAddress parseIpAddress(const EString &str);
894  Void parsePorts(const EString &str, PortVec &ports);
895  Void parseOptions(const EString &str);
896 
897  EString orig_;
898  Action action_;
899  Direction dir_;
900  Protocol proto_;
901  EIpAddress src_;
902  PortVec srcPorts_;
903  EIpAddress dst_;
904  PortVec dstPorts_;
905  OptionPtrVec options_;
906 };
907 
908 namespace std
909 {
911 template <>
912 struct hash<EIpFilterRule::Port>
913 {
914  std::size_t operator()(const EIpFilterRule::Port &port) const noexcept
915  {
916  size_t firsthash = std::hash<UShort>{}(port.first());
917  size_t lasthash = std::hash<UShort>{}(port.last());
918  return EMurmurHash64::combine(firsthash, lasthash);
919  }
920 };
922 template <>
923 struct hash<EIpFilterRule::PortVec>
924 {
925  std::size_t operator()(const EIpFilterRule::PortVec &pv) const noexcept
926  {
927  size_t hash = 0xc70f6907UL;
928  for (auto port : pv)
929  {
930  size_t porthash = std::hash<EIpFilterRule::Port>{}(port);
931  hash = EMurmurHash64::combine(hash, porthash);
932  }
933  return hash;
934  }
935 };
937 template <>
938 struct hash<EIpFilterRule::Option>
939 {
940  std::size_t operator()(const EIpFilterRule::Option &option) const noexcept
941  {
942  return option.hash();
943  }
944 };
946 template <>
947 struct hash<EIpFilterRule::OptionPtrVec>
948 {
949  std::size_t operator()(const EIpFilterRule::OptionPtrVec &options) const noexcept
950  {
951  size_t hash = 0xc70f6907UL;
952  for (auto option : options)
953  hash = EMurmurHash64::combine(hash, option->hash());
954  return hash;
955  }
956 };
958 template <>
959 struct hash<EIpFilterRule>
960 {
961  std::size_t operator()(const EIpFilterRule &r) const noexcept
962  {
963  size_t hash = 0xc70f6907UL;
964  hash = EMurmurHash64::combine(hash, std::hash<Int>{}(static_cast<Int>(r.action())));
965  hash = EMurmurHash64::combine(hash, std::hash<Int>{}(static_cast<Int>(r.direction())));
966  hash = EMurmurHash64::combine(hash, std::hash<Int>{}(static_cast<Int>(r.protocol())));
967  hash = EMurmurHash64::combine(hash, std::hash<EIpAddress>{}(r.source()));
968  hash = EMurmurHash64::combine(hash, std::hash<EIpFilterRule::PortVec>{}(r.sourcePorts()));
969  hash = EMurmurHash64::combine(hash, std::hash<EIpAddress>{}(r.destination()));
970  hash = EMurmurHash64::combine(hash, std::hash<EIpFilterRule::PortVec>{}(r.destinationPorts()));
972  return hash;
973  }
974 };
975 
976 typedef std::shared_ptr<EIpFilterRule> EIpFilterRulePtr;
977 typedef std::list<EIpFilterRule> EIpFilterRuleList;
978 typedef std::list<EIpFilterRulePtr> EIpFilterRulePtrList;
979 
980 } // namespace std
981 
982 
983 #endif // #ifndef __eip_h_included
EIpFilterRule & addSourcePort(UShort first=0, UShort last=0)
Sets the source port for this IPFilterRule.
Definition: eip.h:844
UChar maskWidth() const
Returns the mask width (number of signficant bits) for this address object.
Definition: eip.h:234
Action
Definition: eip.h:327
std::size_t operator()(const EIpFilterRule::Port &port) const noexcept
Definition: eip.h:914
#define True
True.
Definition: ebase.h:25
EIpFilterRule & setProtocol(Protocol proto)
Sets the protocol for this IPFilterRule.
Definition: eip.h:819
Port(const Port &p)
Copy constructor.
Definition: eip.h:472
EIpFilterRule & setAction(Action action)
Sets the action for this IPFilterRule.
Definition: eip.h:803
IcmpTypes & setTypes(const std::string &types)
Definition: eip.h:702
Bool isAny() const
determines if this IP address represents "any".
Definition: eip.h:271
const PortVec & sourcePorts() const
Returns the collection of source ports.
Definition: eip.h:771
Fragment()
Definition: eip.h:543
IcmpTypes & setTypes(cpChar types)
Definition: eip.h:692
const EIpAddress & source() const
Returns the source IP address.
Definition: eip.h:769
EIpFilterRule & addDestinationPort(const Port &p)
Sets the destination port for this IPFilterRule.
Definition: eip.h:869
IcmpTypes(cpChar types)
Definition: eip.h:688
EIpAddress & setMaskWidth(UChar maskWidth)
Assigns the mask width, in number of bits, for this address object.
Definition: eip.h:247
const EIpAddress & destination() const
Returns the destination IP address.
Definition: eip.h:773
Option & setType(OptionType t)
Definition: eip.h:526
Direction
Definition: eip.h:333
#define RAW
Definition: egetopt.cpp:31
Port & setLast(UShort last)
sets the last port in the range.
Definition: eip.h:494
std::size_t operator()(const EIpFilterRule::Option &option) const noexcept
Definition: eip.h:940
in_addr ipv4
Definition: eip.h:287
EIpAddress & operator=(const in_addr &addr)
Assignment operator.
Definition: eip.h:139
EIpAddress(const EIpAddress &ipaddr)
Copy constructor.
Definition: eip.h:65
EIpAddress & setAny(sa_family_t family)
Sets the IP address as "any" for the specified address family.
Definition: eip.h:261
EIpAddress & operator=(const EIpAddress &ipaddr)
Assignment operator.
Definition: eip.h:107
virtual ~IcmpTypes()
Definition: eip.h:690
STL namespace.
const EString & flags()
Definition: eip.h:656
Represents an IPFilterRule "ipoptions" option.
Definition: eip.h:553
EIpFilterRule()
Default constructor.
Definition: eip.h:719
Bool operator==(const EIpAddress &ip) const
Assignment operator.
Definition: eip.h:165
EIpFilterRule & setDirection(Direction dir)
Sets the direction for this IPFilterRule.
Definition: eip.h:811
EIpAddress & operator=(const in6_addr &addr)
Assignment operator.
Definition: eip.h:152
Generates a hash value for the EIpFilterRule::PortVec object.
Definition: eip.h:923
virtual ~TcpOptions()
Definition: eip.h:595
EIpFilterRule & setOriginal(const std::string &orig)
Definition: eip.h:793
size_t hash() const
Definition: eip.h:672
TcpFlags()
Definition: eip.h:652
TcpOptions & setSpec(const std::string &spec)
Definition: eip.h:607
virtual ~Setup()
Definition: eip.h:641
size_t hash() const
Definition: eip.h:630
EIpFilterRule & parse(cpChar raw)
Parses the IPFilterRule definition.
Definition: eip.h:877
Represents an IPFilterRule as defined by RFC 6733.
Definition: eip.h:324
EIpFilterRule(cpChar raw)
Class constructor.
Definition: eip.h:722
Represents an IPFilterRule "setup" option.
Definition: eip.h:637
std::size_t operator()(const EIpAddress &addr) const noexcept
Definition: eip.h:299
Represents an IPFilterRule "tcpflags" option.
Definition: eip.h:649
Represents an IPFilterRule "established" option.
Definition: eip.h:625
std::list< EIpFilterRule > EIpFilterRuleList
Definition: eip.h:977
Represents an IPFilterRule "icmptypes" option.
Definition: eip.h:684
Represents an IPFilterRule "tcpoptions" option.
Definition: eip.h:589
TcpOptions & setSpec(const EString &spec)
Definition: eip.h:602
DECLARE_ERROR_ADVANCED4(EIpFilterRule_InvalidAction)
const EString & original() const
The original IPFilterRule string.
Definition: eip.h:761
const Protocol protocol() const
Returns the protocol for this IPFilterRule.
Definition: eip.h:767
TcpOptions()
Definition: eip.h:592
#define False
False.
Definition: ebase.h:27
std::size_t operator()(const EIpFilterRule::OptionPtrVec &options) const noexcept
Definition: eip.h:949
size_t hash() const
Definition: eip.h:577
std::shared_ptr< EIpFilterRule > EIpFilterRulePtr
Definition: eip.h:976
EIpAddress & operator=(cpStr addr)
Assignment operator.
Definition: eip.h:80
size_t hash() const
Definition: eip.h:642
IpOptions & setSpec(const EString &spec)
Definition: eip.h:566
TcpOptions & setSpec(cpChar spec)
Definition: eip.h:597
EIpFilterRule & operator=(const EIpFilterRule &r)
Assignment operator.
Definition: eip.h:740
size_t hash() const
Definition: eip.h:613
std::string address(Bool includeMask=True) const
Retrieves a string object that is the string representation of the IP address.
Definition: eip.h:198
size_t hash() const
Definition: eip.h:707
Represents an IPFilterRule "frag" option.
Definition: eip.h:540
const Action action() const
Returns the action for this IPFilterRule.
Definition: eip.h:763
IcmpTypes & setTypes(const EString &types)
Definition: eip.h:697
const EString & types()
Definition: eip.h:691
Option(OptionType t)
Definition: eip.h:522
TcpFlags(cpChar flags)
Definition: eip.h:653
std::shared_ptr< Option > OptionPtr
Definition: eip.h:536
EIpAddress(cpStr addr)
Class constructor.
Definition: eip.h:51
TcpFlags & setFlags(const std::string &flags)
Definition: eip.h:667
std::vector< OptionPtr > OptionPtrVec
Definition: eip.h:537
Option()
Definition: eip.h:521
Represents an IP address with mask.
Definition: eip.h:40
Setup()
Definition: eip.h:640
Hash calculation functions for strings and byte arrays.
virtual ~IpOptions()
Definition: eip.h:559
IpOptions()
Definition: eip.h:556
const in_addr & ipv4Address() const
Returns a reference to the in_addr structure that represents an IPv4 address.
Definition: eip.h:225
const EString & spec()
Definition: eip.h:560
const sa_family_t family() const
Returns the address family associated with this address object.
Definition: eip.h:231
TcpFlags(const TcpFlags &o)
Definition: eip.h:654
EIpFilterRule & addDestinationPort(UShort first=0, UShort last=0)
Sets the destination port for this IPFilterRule.
Definition: eip.h:861
OptionType type() const
Definition: eip.h:525
Generates a hash value for the EIpFilterRule::Port object.
Definition: eip.h:912
Protocol
Definition: eip.h:350
const PortVec & destinationPorts() const
Returns the collection of destination ports.
Definition: eip.h:775
static size_t combine(size_t h1, size_t h2)
Combines 2 64-bit hash values.
Definition: ehash.h:300
virtual ~Option()
Definition: eip.h:524
IcmpTypes(const IcmpTypes &o)
Definition: eip.h:689
Port(UShort first=0, UShort last=0)
Default constructor.
Definition: eip.h:469
EIpFilterRule(const EIpFilterRule &r)
Copy constructor.
Definition: eip.h:725
EIpAddress & operator=(const struct sockaddr_storage &saddr)
Assignment operator.
Definition: eip.h:123
std::list< EIpFilterRulePtr > EIpFilterRulePtrList
Definition: eip.h:978
in6_addr ipv6
Definition: eip.h:288
Calculates a hash value for the EIpAddress object.
Definition: eip.h:297
Option(const Option &o)
Definition: eip.h:523
EIpAddress()
Default class constructor.
Definition: eip.h:44
static EStringVec split(cpStr s, cpStr delims)
Splits a string into substrings that are based on the characters in the delimiter array...
Definition: eutil.cpp:73
std::size_t operator()(const EIpFilterRule::PortVec &pv) const noexcept
Definition: eip.h:925
EIpFilterRule & setDestination(const EIpAddress &dst)
Sets the destination IP address for this IPFilterRule.
Definition: eip.h:835
UShort last() const
retrieves the last port in the range.
Definition: eip.h:479
virtual ~Fragment()
Definition: eip.h:544
EIpFilterRule & setSource(const EIpAddress &src)
Sets the source IP address for this IPFilterRule.
Definition: eip.h:827
size_t hash() const
Definition: eip.h:546
IcmpTypes()
Definition: eip.h:687
const OptionPtrVec & options() const
Returns a collection of options.
Definition: eip.h:777
EIpFilterRule & operator=(cpStr r)
Assignment operator.
Definition: eip.h:758
TcpFlags & setFlags(const EString &flags)
Definition: eip.h:662
Port & setFirstLast(UShort first, UShort last)
sets the first and last port in the range.
Definition: eip.h:505
static size_t getHash(cChar val, size_t seed=0xc70f6907UL)
Calculates a 64-bit murmur hash for the value.
Definition: ehash.h:273
EIpFilterRule & operator=(const std::string &r)
Assignment operator.
Definition: eip.h:755
EIpAddress & setFamily(const sa_family_t family)
Assigns the address family for this address object.
Definition: eip.h:239
#define DECLARE_ERROR_ADVANCED2(__e__)
Declares exception class derived from EError with an Int as a constructor parameter and developer def...
Definition: eerror.h:69
UShort first() const
retrieves the first port in the range.
Definition: eip.h:476
OptionType
Definition: eip.h:339
The base class for IPFilterRule options.
Definition: eip.h:518
EIpFilterRule & setOriginal(cpChar orig)
Sets the original string value.
Definition: eip.h:783
EIpAddress(const std::string &addr)
Class constructor.
Definition: eip.h:58
Port & setFirst(UShort first)
sets the first port in the range.
Definition: eip.h:484
const in6_addr & ipv6Address() const
Returns a reference to the in6_addr structure that represents an IPv6 address.
Definition: eip.h:228
const Direction direction() const
Returns the direction for this IPFilterRule.
Definition: eip.h:765
String class.
Definition: estring.h:31
virtual ~TcpFlags()
Definition: eip.h:655
Established()
Definition: eip.h:628
Represents a single port or a range of ports.
Definition: eip.h:463
Generates a hash value for the EIpFilterRule::OptionPrtVec object.
Definition: eip.h:947
TcpOptions(cpChar spec)
Definition: eip.h:593
TcpOptions(const TcpOptions &o)
Definition: eip.h:594
IpOptions(cpChar spec)
Definition: eip.h:557
std::vector< Port > PortVec
Definition: eip.h:515
EIpAddress(const struct sockaddr_storage &saddr)
Class constructor.
Definition: eip.h:72
std::size_t operator()(const EIpFilterRule &r) const noexcept
Definition: eip.h:961
virtual ~Established()
Definition: eip.h:629
EIpFilterRule & setOriginal(const EString &orig)
Definition: eip.h:788
const EString & spec()
Definition: eip.h:596
EIpFilterRule & addSourcePort(const Port &p)
Sets the source port for this IPFilterRule.
Definition: eip.h:852
TcpFlags & setFlags(cpChar flags)
Definition: eip.h:657
IpOptions(const IpOptions &o)
Definition: eip.h:558
IpOptions & setSpec(const std::string &spec)
Definition: eip.h:571
IpOptions & setSpec(cpChar spec)
Definition: eip.h:561