...
1 package util
2
3 import (
4 "fmt"
5 "strconv"
6 "strings"
7 )
8
9
10 type PortRange struct {
11 LowerBound int
12 UpperBound int
13 }
14
15
16 func ParsePort(port string) (int, error) {
17 i, err := strconv.Atoi(port)
18 if err != nil || !isPort(i) {
19 return -1, fmt.Errorf("\"%s\" is not a valid TCP port", port)
20 }
21 return i, nil
22 }
23
24
25
26 func ParsePortRange(portRange string) (PortRange, error) {
27 bounds := strings.Split(portRange, "-")
28 if len(bounds) > 2 {
29 return PortRange{}, fmt.Errorf("ranges expected as <lower>-<upper>")
30 }
31 if len(bounds) == 1 {
32
33 bounds = append(bounds, bounds[0])
34 }
35 lower, err := strconv.Atoi(bounds[0])
36 if err != nil || !isPort(lower) {
37 return PortRange{}, fmt.Errorf("\"%s\" is not a valid lower-bound", bounds[0])
38 }
39 upper, err := strconv.Atoi(bounds[1])
40 if err != nil || !isPort(upper) {
41 return PortRange{}, fmt.Errorf("\"%s\" is not a valid upper-bound", bounds[1])
42 }
43 if upper < lower {
44 return PortRange{}, fmt.Errorf("\"%s\": upper-bound must be greater than or equal to lower-bound", portRange)
45 }
46 return PortRange{LowerBound: lower, UpperBound: upper}, nil
47 }
48
49
50
51 func isPort(port int) bool {
52 return 0 <= port && port <= 65535
53 }
54
55
56 func (pr PortRange) Ports() []uint16 {
57 var ports []uint16
58 for i := pr.LowerBound; i <= pr.UpperBound; i++ {
59 ports = append(ports, uint16(i))
60 }
61 return ports
62 }
63
64 func (pr PortRange) ToString() string {
65 if pr.LowerBound == pr.UpperBound {
66 return strconv.Itoa(pr.LowerBound)
67 }
68
69 return fmt.Sprintf("%d-%d", pr.LowerBound, pr.UpperBound)
70 }
71
View as plain text