Skip to content
Snippets Groups Projects
outbound.go 1.35 KiB
package traceroute

import (
	"errors"
	"github.com/jackpal/gateway"
	"net"
)

func getOutboundIP(mode int) (*address, error) {
	ip, err := gateway.DiscoverInterface()
	if err != nil {
		return nil, err
	}

	a := newAddress(ip)

	switch mode {
	case addressV4:
		if isV4(ip) {
			return &a, nil
		}
	case addressV6:
		if !isV4(ip) {
			return &a, nil
		}
	case unknown:
	default:
		return nil, errors.New("the mode parameter must be either 4 or 6")
	}

	interfaces, err := net.Interfaces()

	if err != nil {
		return nil, err
	}

	for _, i := range interfaces {
		addrs, err := i.Addrs()

		if err != nil {
			continue
		}

		var ipv6, ipv4 net.IP
		var found bool

		for _, a := range addrs {
			if a.Network() != "ip+net" {
				continue
			}

			b, _, err := net.ParseCIDR(a.String())
			if err != nil {
				continue
			}

			if !b.IsGlobalUnicast() {
				continue
			}

			if isV4(b) {
				ipv4 = b
			} else {
				ipv6 = b
			}

			if b.String() == ip.String() {
				found = true
			}
		}

		if !found {
			continue
		}

		if mode <= addressV4 {
			if ipv4 == nil {
				return nil, errors.New("no suitable interface was found")
			}

			a:= newAddress(ipv4)
			return &a, nil
		}

		if ipv6 == nil {
			return nil, errors.New("no suitable interface was found")
		}

		a:= newAddress(ipv6)
		return &a, nil

	}

	return nil, errors.New("no suitable interface was found")

}