github.com/geofffranks/garden-linux@v0.0.0-20160715111146-26c893169cfa/network/network.go (about) 1 package network 2 3 import ( 4 "encoding/json" 5 "net" 6 ) 7 8 type Network struct { 9 ipNet *net.IPNet 10 11 hostIP net.IP 12 containerIP net.IP 13 } 14 15 func New(ipNet *net.IPNet) *Network { 16 return &Network{ 17 ipNet: ipNet, 18 hostIP: maxValidIP(ipNet), 19 containerIP: nextIP(ipNet.IP), 20 } 21 } 22 23 func (n Network) IPNet() *net.IPNet { 24 return n.ipNet 25 } 26 27 func (n Network) String() string { 28 return n.ipNet.String() 29 } 30 31 func (n Network) IP() net.IP { 32 return n.ipNet.IP 33 } 34 35 func (n Network) HostIP() net.IP { 36 return n.hostIP 37 } 38 39 func (n Network) ContainerIP() net.IP { 40 return n.containerIP 41 } 42 43 func (n Network) MarshalJSON() ([]byte, error) { 44 return json.Marshal(map[string]interface{}{ 45 "IPNet": n.String(), 46 47 "HostIP": n.HostIP(), 48 "ContainerIP": n.ContainerIP(), 49 }) 50 } 51 52 func (n *Network) CIDRSuffix() int { 53 suff, _ := n.ipNet.Mask.Size() 54 return suff 55 } 56 57 func (n *Network) UnmarshalJSON(data []byte) error { 58 var tmp struct { 59 IPNet string 60 61 HostIP net.IP 62 ContainerIP net.IP 63 } 64 65 err := json.Unmarshal(data, &tmp) 66 if err != nil { 67 return err 68 } 69 70 _, ipNet, err := net.ParseCIDR(tmp.IPNet) 71 if err != nil { 72 return err 73 } 74 75 n.ipNet = ipNet 76 n.hostIP = tmp.HostIP 77 n.containerIP = tmp.ContainerIP 78 79 return nil 80 } 81 82 func maxValidIP(ipn *net.IPNet) net.IP { 83 mask := ipn.Mask 84 min := ipn.IP 85 86 if len(mask) != len(min) { 87 panic("length of mask is not compatible with length of network IP") 88 } 89 90 max := make([]byte, len(min)) 91 for i, b := range mask { 92 max[i] = min[i] | ^b 93 } 94 95 // Do not include the network and broadcast addresses. 96 max[len(max)-1]-- 97 98 return net.IP(max).To16() 99 } 100 101 func nextIP(ip net.IP) net.IP { 102 next := net.ParseIP(ip.String()) 103 inc(next) 104 return next 105 } 106 107 func inc(ip net.IP) { 108 for j := len(ip) - 1; j >= 0; j-- { 109 ip[j]++ 110 if ip[j] > 0 { 111 break 112 } 113 } 114 }