| package ipam |
| |
| import ( |
| "fmt" |
| "net" |
| |
| "github.com/docker/libnetwork/ipamapi" |
| "github.com/docker/libnetwork/types" |
| ) |
| |
| type ipVersion int |
| |
| const ( |
| v4 = 4 |
| v6 = 6 |
| ) |
| |
| func getAddressRange(pool string, masterNw *net.IPNet) (*AddressRange, error) { |
| ip, nw, err := net.ParseCIDR(pool) |
| if err != nil { |
| return nil, ipamapi.ErrInvalidSubPool |
| } |
| lIP, e := types.GetHostPartIP(nw.IP, masterNw.Mask) |
| if e != nil { |
| return nil, fmt.Errorf("failed to compute range's lowest ip address: %v", e) |
| } |
| bIP, e := types.GetBroadcastIP(nw.IP, nw.Mask) |
| if e != nil { |
| return nil, fmt.Errorf("failed to compute range's broadcast ip address: %v", e) |
| } |
| hIP, e := types.GetHostPartIP(bIP, masterNw.Mask) |
| if e != nil { |
| return nil, fmt.Errorf("failed to compute range's highest ip address: %v", e) |
| } |
| nw.IP = ip |
| return &AddressRange{nw, ipToUint64(types.GetMinimalIP(lIP)), ipToUint64(types.GetMinimalIP(hIP))}, nil |
| } |
| |
| // It generates the ip address in the passed subnet specified by |
| // the passed host address ordinal |
| func generateAddress(ordinal uint64, network *net.IPNet) net.IP { |
| var address [16]byte |
| |
| // Get network portion of IP |
| if getAddressVersion(network.IP) == v4 { |
| copy(address[:], network.IP.To4()) |
| } else { |
| copy(address[:], network.IP) |
| } |
| |
| end := len(network.Mask) |
| addIntToIP(address[:end], ordinal) |
| |
| return net.IP(address[:end]) |
| } |
| |
| func getAddressVersion(ip net.IP) ipVersion { |
| if ip.To4() == nil { |
| return v6 |
| } |
| return v4 |
| } |
| |
| // Adds the ordinal IP to the current array |
| // 192.168.0.0 + 53 => 192.168.0.53 |
| func addIntToIP(array []byte, ordinal uint64) { |
| for i := len(array) - 1; i >= 0; i-- { |
| array[i] |= (byte)(ordinal & 0xff) |
| ordinal >>= 8 |
| } |
| } |
| |
| // Convert an ordinal to the respective IP address |
| func ipToUint64(ip []byte) (value uint64) { |
| cip := types.GetMinimalIP(ip) |
| for i := 0; i < len(cip); i++ { |
| j := len(cip) - 1 - i |
| value += uint64(cip[i]) << uint(j*8) |
| } |
| return value |
| } |