github.com/zmap/zlint@v1.1.0/util/ip.go (about) 1 /* 2 * ZLint Copyright 2018 Regents of the University of Michigan 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 * implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 // contains helper functions for ip address lints 16 17 package util 18 19 import ( 20 "fmt" 21 "net" 22 ) 23 24 type subnetCategory int 25 26 const ( 27 privateUse subnetCategory = iota 28 sharedAddressSpace 29 benchmarking 30 documentation 31 reserved 32 protocolAssignment 33 as112 34 amt 35 orchidV2 36 lisp 37 thisHostOnThisNetwork 38 translatableAddress6to4 39 translatableAddress4to6 40 dummyAddress 41 portControlProtocolAnycast 42 traversalUsingRelaysAroundNATAnycast 43 nat64DNS64Discovery 44 limitedBroadcast 45 discardOnly 46 teredo 47 uniqueLocal 48 linkLocalUnicast 49 ianaReservedForFutureUse 50 ianaReservedMulticast 51 ) 52 53 var reservedNetworks []*net.IPNet 54 55 // IsIANAReserved checks IP validity as per IANA reserved IPs 56 // IPv4 57 // https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml 58 // https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml 59 // IPv6 60 // https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml 61 // https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml 62 func IsIANAReserved(ip net.IP) bool { 63 if !ip.IsGlobalUnicast() { 64 return true 65 } 66 67 for _, network := range reservedNetworks { 68 if network.Contains(ip) { 69 return true 70 } 71 } 72 73 return false 74 } 75 76 func init() { 77 var networks = map[subnetCategory][]string{ 78 privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, 79 sharedAddressSpace: {"100.64.0.0/10"}, 80 benchmarking: {"198.18.0.0/15", "2001:2::/48"}, 81 documentation: {"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24", "2001:db8::/32"}, 82 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 83 protocolAssignment: {"192.0.0.0/24", "2001::/23"}, // 192.0.0.0/24 contains 192.0.0.0/29 - IPv4 Service Continuity Prefix 84 as112: {"192.31.196.0/24", "192.175.48.0/24", "2001:4:112::/48", "2620:4f:8000::/48"}, 85 amt: {"192.52.193.0/24", "2001:3::/32"}, 86 orchidV2: {"2001:20::/28"}, 87 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 88 thisHostOnThisNetwork: {"0.0.0.0/8"}, 89 translatableAddress4to6: {"2002::/16"}, 90 translatableAddress6to4: {"64:ff9b::/96", "64:ff9b:1::/48"}, 91 dummyAddress: {"192.0.0.8/32"}, 92 portControlProtocolAnycast: {"192.0.0.9/32", "2001:1::1/128"}, 93 traversalUsingRelaysAroundNATAnycast: {"192.0.0.10/32", "2001:1::2/128"}, 94 nat64DNS64Discovery: {"192.0.0.170/32", "192.0.0.171/32"}, 95 limitedBroadcast: {"255.255.255.255/32"}, 96 discardOnly: {"100::/64"}, 97 teredo: {"2001::/32"}, 98 uniqueLocal: {"fc00::/7"}, 99 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) 100 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"}, 101 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) 102 } 103 104 for _, netList := range networks { 105 for _, network := range netList { 106 var ipNet *net.IPNet 107 var err error 108 109 if _, ipNet, err = net.ParseCIDR(network); err != nil { 110 panic(fmt.Sprintf("unexpected internal network value provided: %s", err.Error())) 111 } 112 reservedNetworks = append(reservedNetworks, ipNet) 113 } 114 } 115 }