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  }