github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/utils/portspec/portspec.go (about) 1 package portspec 2 3 // This package manages all port spec functions and validations and can 4 // be reused by all other packages. 5 6 import ( 7 "errors" 8 "strconv" 9 "strings" 10 ) 11 12 // PortSpec is the specification of a port or port range 13 type PortSpec struct { 14 Min uint16 `json:"Min,omitempty"` 15 Max uint16 `json:"Max,omitempty"` 16 value interface{} 17 } 18 19 // NewPortSpec creates a new port spec 20 func NewPortSpec(min, max uint16, value interface{}) (*PortSpec, error) { 21 22 if min > max { 23 return nil, errors.New("Min port greater than max") 24 } 25 26 return &PortSpec{ 27 Min: min, 28 Max: max, 29 value: value, 30 }, nil 31 } 32 33 // NewPortSpecFromString creates a new port spec 34 func NewPortSpecFromString(ports string, value interface{}) (*PortSpec, error) { 35 36 var min, max int 37 var err error 38 if strings.Contains(ports, ":") { 39 portMinMax := strings.SplitN(ports, ":", 2) 40 if len(portMinMax) != 2 { 41 return nil, errors.New("Invalid port specification") 42 } 43 44 min, err = strconv.Atoi(portMinMax[0]) 45 if err != nil || min < 0 { 46 return nil, errors.New("Min is not a valid port") 47 } 48 49 max, err = strconv.Atoi(portMinMax[1]) 50 if err != nil || max >= 65536 { 51 return nil, errors.New("Max is not a valid port") 52 } 53 } else { 54 min, err = strconv.Atoi(ports) 55 if err != nil || min >= 65536 || min < 0 { 56 return nil, errors.New("Port is larger than 2^16 or invalid port") 57 } 58 max = min 59 } 60 61 return NewPortSpec(uint16(min), uint16(max), value) 62 } 63 64 // IsMultiPort returns true if the spec is for multiple ports. 65 func (s *PortSpec) IsMultiPort() bool { 66 return s.Min != s.Max 67 } 68 69 // SinglePort returns the port of a non multi-port spec 70 func (s *PortSpec) SinglePort() (uint16, error) { 71 if s.IsMultiPort() { 72 return 0, errors.New("Not a single port specification") 73 } 74 75 return s.Min, nil 76 } 77 78 // Range returns the range of a spec. 79 func (s *PortSpec) Range() (uint16, uint16) { 80 return s.Min, s.Max 81 } 82 83 // MultiPort returns the multi-port range as a string. 84 func (s *PortSpec) String() string { 85 if s.IsMultiPort() { 86 return strconv.Itoa(int(s.Min)) + ":" + strconv.Itoa(int(s.Max)) 87 } 88 89 return strconv.Itoa(int(s.Min)) 90 } 91 92 // Value returns the value of the portspec if one is there 93 func (s *PortSpec) Value() interface{} { 94 return s.value 95 } 96 97 // Overlaps returns true if the provided port spec overlaps with the given one. 98 func (s *PortSpec) Overlaps(p *PortSpec) bool { 99 a := p 100 b := s 101 if a.Min > b.Min { 102 a = s 103 b = p 104 } 105 if a.Max >= b.Min { 106 return true 107 } 108 return false 109 } 110 111 // Intersects returns true if the provided port spec intersect with the given one. 112 func (s *PortSpec) Intersects(p *PortSpec) bool { 113 if p.Min == p.Max { 114 return s.IsIncluded(int(p.Min)) 115 } 116 return s.IsIncluded(int(p.Min)) && s.IsIncluded(int(p.Max)) 117 } 118 119 // IsIncluded returns trues if a port is within the range of the portspec 120 func (s *PortSpec) IsIncluded(port int) bool { 121 p := uint16(port) 122 if s.Min <= p && p <= s.Max { 123 return true 124 } 125 return false 126 }