116 lines
5.1 KiB
Go
116 lines
5.1 KiB
Go
/*
|
|
* ZLint Copyright 2018 Regents of the University of Michigan
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
* use this file except in compliance with the License. You may obtain a copy
|
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*/
|
|
|
|
// contains helper functions for ip address lints
|
|
|
|
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
type subnetCategory int
|
|
|
|
const (
|
|
privateUse subnetCategory = iota
|
|
sharedAddressSpace
|
|
benchmarking
|
|
documentation
|
|
reserved
|
|
protocolAssignment
|
|
as112
|
|
amt
|
|
orchidV2
|
|
lisp
|
|
thisHostOnThisNetwork
|
|
translatableAddress6to4
|
|
translatableAddress4to6
|
|
dummyAddress
|
|
portControlProtocolAnycast
|
|
traversalUsingRelaysAroundNATAnycast
|
|
nat64DNS64Discovery
|
|
limitedBroadcast
|
|
discardOnly
|
|
teredo
|
|
uniqueLocal
|
|
linkLocalUnicast
|
|
ianaReservedForFutureUse
|
|
ianaReservedMulticast
|
|
)
|
|
|
|
var reservedNetworks []*net.IPNet
|
|
|
|
// IsIANAReserved checks IP validity as per IANA reserved IPs
|
|
// IPv4
|
|
// https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
|
|
// https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml
|
|
// IPv6
|
|
// https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
|
|
// https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
|
|
func IsIANAReserved(ip net.IP) bool {
|
|
if !ip.IsGlobalUnicast() {
|
|
return true
|
|
}
|
|
|
|
for _, network := range reservedNetworks {
|
|
if network.Contains(ip) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func init() {
|
|
var networks = map[subnetCategory][]string{
|
|
privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
|
|
sharedAddressSpace: {"100.64.0.0/10"},
|
|
benchmarking: {"198.18.0.0/15", "2001:2::/48"},
|
|
documentation: {"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24", "2001:db8::/32"},
|
|
reserved: {"240.0.0.0/4", "0400::/6", "0800::/5", "1000::/4", "4000::/3", "6000::/3", "8000::/3", "a000::/3", "c000::/3", "e000::/4", "f000::/5", "f800::/6", "fe00::/9"}, // https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
|
|
protocolAssignment: {"192.0.0.0/24", "2001::/23"}, // 192.0.0.0/24 contains 192.0.0.0/29 - IPv4 Service Continuity Prefix
|
|
as112: {"192.31.196.0/24", "192.175.48.0/24", "2001:4:112::/48", "2620:4f:8000::/48"},
|
|
amt: {"192.52.193.0/24", "2001:3::/32"},
|
|
orchidV2: {"2001:20::/28"},
|
|
lisp: {"2001:5::/32"}, // TODO: this could expire at 2019-09. Please check https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml for updates
|
|
thisHostOnThisNetwork: {"0.0.0.0/8"},
|
|
translatableAddress4to6: {"2002::/16"},
|
|
translatableAddress6to4: {"64:ff9b::/96", "64:ff9b:1::/48"},
|
|
dummyAddress: {"192.0.0.8/32"},
|
|
portControlProtocolAnycast: {"192.0.0.9/32", "2001:1::1/128"},
|
|
traversalUsingRelaysAroundNATAnycast: {"192.0.0.10/32", "2001:1::2/128"},
|
|
nat64DNS64Discovery: {"192.0.0.170/32", "192.0.0.171/32"},
|
|
limitedBroadcast: {"255.255.255.255/32"},
|
|
discardOnly: {"100::/64"},
|
|
teredo: {"2001::/32"},
|
|
uniqueLocal: {"fc00::/7"},
|
|
linkLocalUnicast: {"fe80::/10", "169.254.0.0/16"}, // this range is covered by ip.IsLinkLocalUnicast(), which is in turn called by net.IP.IsGlobalUnicast(ip)
|
|
ianaReservedForFutureUse: {"255.0.0.0/8", "254.0.0.0/8", "253.0.0.0/8", "252.0.0.0/8", "251.0.0.0/8", "250.0.0.0/8", "249.0.0.0/8", "248.0.0.0/8", "247.0.0.0/8", "246.0.0.0/8", "245.0.0.0/8", "244.0.0.0/8", "243.0.0.0/8", "242.0.0.0/8", "241.0.0.0/8", "240.0.0.0/8"},
|
|
ianaReservedMulticast: {"239.0.0.0/8", "238.0.0.0/8", "237.0.0.0/8", "236.0.0.0/8", "235.0.0.0/8", "234.0.0.0/8", "233.0.0.0/8", "232.0.0.0/8", "231.0.0.0/8", "230.0.0.0/8", "229.0.0.0/8", "228.0.0.0/8", "227.0.0.0/8", "226.0.0.0/8", "225.0.0.0/8", "224.0.0.0/8", "ff00::/8"}, // this range is covered by ip.IsMulticast() call, which is in turn called by net.IP.IsGlobalUnicast(ip)
|
|
}
|
|
|
|
for _, netList := range networks {
|
|
for _, network := range netList {
|
|
var ipNet *net.IPNet
|
|
var err error
|
|
|
|
if _, ipNet, err = net.ParseCIDR(network); err != nil {
|
|
panic(fmt.Sprintf("unexpected internal network value provided: %s", err.Error()))
|
|
}
|
|
reservedNetworks = append(reservedNetworks, ipNet)
|
|
}
|
|
}
|
|
}
|