NetFirstAndLastIP takes the beginning address of an entire network in CIDR notation (e.g. 192.168.1.0/24) and returns the first and last IP addresses within the network (e.g. first 192.168.1.0, last 192.168.1.255). Note that these are the first and last IP addresses, not the first and last *usable*
(networkCIDR string)
| 54 | // *usable* IP addresses (which would be 192.168.1.1 and 192.168.1.254, |
| 55 | // respectively, for 192.168.1.0/24). |
| 56 | func NetFirstAndLastIP(networkCIDR string) (first, last net.IP, err error) { |
| 57 | _, subnet, err := net.ParseCIDR(networkCIDR) |
| 58 | if err != nil { |
| 59 | return nil, nil, err |
| 60 | } |
| 61 | |
| 62 | first = make(net.IP, len(subnet.IP)) |
| 63 | last = make(net.IP, len(subnet.IP)) |
| 64 | |
| 65 | switch len(subnet.IP) { |
| 66 | case net.IPv4len: |
| 67 | mask := binary.BigEndian.Uint32(subnet.Mask) |
| 68 | ip := binary.BigEndian.Uint32(subnet.IP) |
| 69 | // To achieve the first IP address, we need to AND the IP with the mask. |
| 70 | // The AND operation will set all bits in the host part to 0. |
| 71 | binary.BigEndian.PutUint32(first, ip&mask) |
| 72 | // To achieve the last IP address, we need to OR the IP network with the inverted mask. |
| 73 | // The AND between the IP and the mask will set all bits in the host part to 0, keeping the network part. |
| 74 | // The XOR between the mask and 0xffffffff will set all bits in the host part to 1, and the network part to 0. |
| 75 | // The OR operation will keep the host part unchanged, and sets the host part to all 1. |
| 76 | binary.BigEndian.PutUint32(last, (ip&mask)|(mask^0xffffffff)) |
| 77 | case net.IPv6len: |
| 78 | mask1 := binary.BigEndian.Uint64(subnet.Mask[:8]) |
| 79 | mask2 := binary.BigEndian.Uint64(subnet.Mask[8:]) |
| 80 | ip1 := binary.BigEndian.Uint64(subnet.IP[:8]) |
| 81 | ip2 := binary.BigEndian.Uint64(subnet.IP[8:]) |
| 82 | binary.BigEndian.PutUint64(first[:8], ip1&mask1) |
| 83 | binary.BigEndian.PutUint64(first[8:], ip2&mask2) |
| 84 | binary.BigEndian.PutUint64(last[:8], (ip1&mask1)|(mask1^0xffffffffffffffff)) |
| 85 | binary.BigEndian.PutUint64(last[8:], (ip2&mask2)|(mask2^0xffffffffffffffff)) |
| 86 | } |
| 87 | |
| 88 | return first, last, nil |
| 89 | } |
searching dependent graphs…