github.com/ethereum/go-ethereum@v1.16.1/p2p/netutil/addrutil.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package netutil 18 19 import ( 20 "fmt" 21 "math/rand" 22 "net" 23 "net/netip" 24 ) 25 26 // AddrAddr gets the IP address contained in addr. The result will be invalid if the 27 // address type is unsupported. 28 func AddrAddr(addr net.Addr) netip.Addr { 29 switch a := addr.(type) { 30 case *net.IPAddr: 31 return IPToAddr(a.IP) 32 case *net.TCPAddr: 33 return IPToAddr(a.IP) 34 case *net.UDPAddr: 35 return IPToAddr(a.IP) 36 default: 37 return netip.Addr{} 38 } 39 } 40 41 // IPToAddr converts net.IP to netip.Addr. Note that unlike netip.AddrFromSlice, this 42 // function will always ensure that the resulting Addr is IPv4 when the input is. 43 func IPToAddr(ip net.IP) netip.Addr { 44 if ip4 := ip.To4(); ip4 != nil { 45 addr, _ := netip.AddrFromSlice(ip4) 46 return addr 47 } else if ip6 := ip.To16(); ip6 != nil { 48 addr, _ := netip.AddrFromSlice(ip6) 49 return addr 50 } 51 return netip.Addr{} 52 } 53 54 // RandomAddr creates a random IP address. 55 func RandomAddr(rng *rand.Rand, ipv4 bool) netip.Addr { 56 var bytes []byte 57 if ipv4 || rng.Intn(2) == 0 { 58 bytes = make([]byte, 4) 59 } else { 60 bytes = make([]byte, 16) 61 } 62 rng.Read(bytes) 63 addr, ok := netip.AddrFromSlice(bytes) 64 if !ok { 65 panic(fmt.Errorf("BUG! invalid IP %v", bytes)) 66 } 67 return addr 68 }