Jerry YY Rain
Jerry YY Rain

Reputation: 4382

How do I get the local IP address in Go?

I want to get the computer's IP address. I used the code below, but it returns 127.0.0.1.

I want to get the IP address, such as 10.32.10.111, instead of the loopback address.

name, err := os.Hostname()
if err != nil {
     fmt.Printf("Oops: %v\n", err)
     return
}

addrs, err := net.LookupHost(name)
if err != nil {
    fmt.Printf("Oops: %v\n", err)
    return
}

for _, a := range addrs {
    fmt.Println(a)
}  

Upvotes: 111

Views: 174631

Answers (9)

Mr.Wang from Next Door
Mr.Wang from Next Door

Reputation: 14780

Here is a better solution to retrieve the preferred outbound ip address when there are multiple ip interfaces exist on the machine.

import (
    "log"
    "net"
)

// Get preferred outbound ip of this machine
func GetOutboundIP() net.IP {
    conn, err := net.Dial("udp", "8.8.8.8:80")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    localAddr := conn.LocalAddr().(*net.UDPAddr)

    return localAddr.IP
}

Upvotes: 203

Superlocrian
Superlocrian

Reputation: 11

var (
    ret    net.IP
    err    error
    ifaces []net.Interface
    addrs  []net.Addr
)
if ifaces, err = net.Interfaces(); err == nil {
    for _, i := range ifaces {
        if addrs, err = i.Addrs(); err == nil {
            for _, a := range addrs {
                if ipnet, ok := a.(*net.IPNet); ok {
                    if ipv4 := ipnet.IP.To4(); ipv4 != nil {
                        if ipv4.IsGlobalUnicast() {
                            ret = ipv4
                        }
                    }
                }
            }
        }
    }
}
return ret

Works for me.

Upvotes: -2

Inasa Xia
Inasa Xia

Reputation: 501

If you only have one IP address except 127.0.0.1, You can check the code down here.

conn,err := net.Dial("ip:icmp","google.com")
fmt.Println(conn.LocalAddr())

The second parameter can be any IP address except 127.0.0.1

Upvotes: 0

Darlan Dieterich
Darlan Dieterich

Reputation: 2537

func GetInternalIP() string {
    itf, _ := net.InterfaceByName("enp1s0") //here your interface
    item, _ := itf.Addrs()
    var ip net.IP
    for _, addr := range item {
        switch v := addr.(type) {
        case *net.IPNet:
            if !v.IP.IsLoopback() {
                if v.IP.To4() != nil {//Verify if IP is IPV4
                    ip = v.IP
                }
            }
        }
    }
    if ip != nil {
        return ip.String()
    } else {
        return ""
    }
}

Upvotes: 4

Sebastian
Sebastian

Reputation: 17413

You need to loop through all network interfaces

ifaces, err := net.Interfaces()
// handle err
for _, i := range ifaces {
    addrs, err := i.Addrs()
    // handle err
    for _, addr := range addrs {
        var ip net.IP
        switch v := addr.(type) {
        case *net.IPNet:
                ip = v.IP
        case *net.IPAddr:
                ip = v.IP
        }
        // process IP address
    }
}

Play (taken from util/helper.go)

Upvotes: 154

Abdul Wasae
Abdul Wasae

Reputation: 3688

func resolveHostIp() (string) {

    netInterfaceAddresses, err := net.InterfaceAddrs()

    if err != nil { return "" }

    for _, netInterfaceAddress := range netInterfaceAddresses {

        networkIp, ok := netInterfaceAddress.(*net.IPNet)

        if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil {

            ip := networkIp.IP.String()

            fmt.Println("Resolved Host IP: " + ip)

            return ip
        }
    }
    return ""
}

Upvotes: 2

Shane Jarvie
Shane Jarvie

Reputation: 511

To ensure that you get a non-loopback address, simply check that an IP is not a loopback when you are iterating.

// GetLocalIP returns the non loopback local IP of the host
func GetLocalIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        return ""
    }
    for _, address := range addrs {
        // check the address type and if it is not a loopback the display it
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }
    return ""
}

Upvotes: 51

eric gilbertson
eric gilbertson

Reputation: 1003

This worked for me:

host, _ := os.Hostname()
addrs, _ := net.LookupIP(host)
for _, addr := range addrs {
    if ipv4 := addr.To4(); ipv4 != nil {
        fmt.Println("IPv4: ", ipv4)
    }   
}

Unlike the poster's example, it returns only non-loopback addresses, e.g. 10.120.X.X.

Upvotes: 17

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137398

net.LookupHost() on your os.Hostname() is probably always going to give you 127.0.0.1, because that's what's in your /etc/hosts or equivalent.

I think what you want to use is net.InterfaceAddrs():

func InterfaceAddrs() ([]Addr, error)

InterfaceAddrs returns a list of the system's network interface addresses.

Upvotes: 26

Related Questions