istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/util/net/ip.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package net
    16  
    17  import (
    18  	"net"
    19  	"net/http"
    20  	"net/netip"
    21  
    22  	"istio.io/istio/pkg/log"
    23  )
    24  
    25  // IsValidIPAddress Tell whether the given IP address is valid or not
    26  func IsValidIPAddress(ip string) bool {
    27  	ipa, err := netip.ParseAddr(ip)
    28  	if err != nil {
    29  		return false
    30  	}
    31  	return ipa.IsValid()
    32  }
    33  
    34  // IsIPv6Address returns if ip is IPv6.
    35  func IsIPv6Address(ip string) bool {
    36  	ipa, err := netip.ParseAddr(ip)
    37  	if err != nil {
    38  		return false
    39  	}
    40  	return ipa.Is6()
    41  }
    42  
    43  // IsIPv4Address returns if ip is IPv4.
    44  func IsIPv4Address(ip string) bool {
    45  	ipa, err := netip.ParseAddr(ip)
    46  	if err != nil {
    47  		return false
    48  	}
    49  	return ipa.Is4()
    50  }
    51  
    52  // IPsSplitV4V6 returns two slice of ipv4 and ipv6 string slice.
    53  func IPsSplitV4V6(ips []string) (ipv4 []string, ipv6 []string) {
    54  	for _, i := range ips {
    55  		ip, err := netip.ParseAddr(i)
    56  		if err != nil {
    57  			log.Debugf("ignoring un-parsable IP address: %v", err)
    58  			continue
    59  		}
    60  		if ip.Is4() {
    61  			ipv4 = append(ipv4, ip.String())
    62  		} else if ip.Is6() {
    63  			ipv6 = append(ipv6, ip.String())
    64  		} else {
    65  			log.Debugf("ignoring un-parsable IP address: %v", ip)
    66  		}
    67  	}
    68  	return
    69  }
    70  
    71  // ParseIPsSplitToV4V6 returns two slice of ipv4 and ipv6 netip.Addr.
    72  func ParseIPsSplitToV4V6(ips []string) (ipv4 []netip.Addr, ipv6 []netip.Addr) {
    73  	for _, i := range ips {
    74  		ip, err := netip.ParseAddr(i)
    75  		if err != nil {
    76  			log.Debugf("ignoring un-parsable IP address: %v", err)
    77  			continue
    78  		}
    79  		if ip.Is4() {
    80  			ipv4 = append(ipv4, ip)
    81  		} else if ip.Is6() {
    82  			ipv6 = append(ipv6, ip)
    83  		} else {
    84  			log.Debugf("ignoring un-parsable IP address: %v", ip)
    85  		}
    86  	}
    87  	return
    88  }
    89  
    90  // IsRequestFromLocalhost returns true if request is from localhost address.
    91  func IsRequestFromLocalhost(r *http.Request) bool {
    92  	ip, _, err := net.SplitHostPort(r.RemoteAddr)
    93  	if err != nil {
    94  		return false
    95  	}
    96  
    97  	userIP := net.ParseIP(ip)
    98  	return userIP.IsLoopback()
    99  }