-
Notifications
You must be signed in to change notification settings - Fork 0
/
ipnet.go
52 lines (48 loc) · 1.32 KB
/
ipnet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/* ipnet.go: wraps the net.IPNet object to make it yaml parsable
*
* Authors: J. Lowell Wofford <[email protected]> & Brett Holman <[email protected]>
*
* This software is open source software available under the BSD-3 license.
* Copyright (c) 2020, Triad National Security, LLC
* See LICENSE file for details.
*/
package main
import (
"fmt"
"net"
"strconv"
"strings"
)
// IPNet wraps net.IPNet this is used to unmarshal IPNets because net doesn't provide this function
type IPNet net.IPNet
// UnmarshalText decodes text of the form IP/MASK to an IPNET where MASK is either CIDR notation or dotted decimals
func (i *IPNet) UnmarshalText(text []byte) error {
// split into net and mask
p := strings.Split(string(text), "/")
if len(p) != 2 {
return fmt.Errorf("invalid IPNet: %s", text)
}
// parse net
if err := i.IP.UnmarshalText([]byte(p[0])); err != nil {
return err
}
// parse mask
m := strings.Split(p[1], ".")
switch len(m) {
case 1:
c, err := strconv.Atoi(m[0])
if err != nil || c > 32 {
return fmt.Errorf("invalid IPMask: %s", p[1])
}
i.Mask = net.CIDRMask(c, 32)
case 4:
var ip net.IP
if err := ip.UnmarshalText([]byte(p[1])); err != nil {
return fmt.Errorf("invalid IPMask: %s", p[1])
}
i.Mask = net.IPMask(ip.To4())
default:
return fmt.Errorf("invalid IPMask: %s", p[1])
}
return nil
}