github.com/MerlinKodo/sing-tun@v0.1.15/tun.go (about)

     1  package tun
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  	"net/netip"
     7  	"runtime"
     8  	"strconv"
     9  	"strings"
    10  
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  	F "github.com/sagernet/sing/common/format"
    13  	"github.com/sagernet/sing/common/logger"
    14  	N "github.com/sagernet/sing/common/network"
    15  	"github.com/sagernet/sing/common/ranges"
    16  )
    17  
    18  type Handler interface {
    19  	N.TCPConnectionHandler
    20  	N.UDPConnectionHandler
    21  	E.Handler
    22  }
    23  
    24  type Tun interface {
    25  	io.ReadWriter
    26  	CreateVectorisedWriter() N.VectorisedWriter
    27  	Close() error
    28  }
    29  
    30  type WinTun interface {
    31  	Tun
    32  	ReadPacket() ([]byte, func(), error)
    33  }
    34  
    35  type Options struct {
    36  	Name                     string
    37  	Inet4Address             []netip.Prefix
    38  	Inet6Address             []netip.Prefix
    39  	MTU                      uint32
    40  	AutoRoute                bool
    41  	StrictRoute              bool
    42  	Inet4RouteAddress        []netip.Prefix
    43  	Inet6RouteAddress        []netip.Prefix
    44  	Inet4RouteExcludeAddress []netip.Prefix
    45  	Inet6RouteExcludeAddress []netip.Prefix
    46  	IncludeInterface         []string
    47  	ExcludeInterface         []string
    48  	IncludeUID               []ranges.Range[uint32]
    49  	ExcludeUID               []ranges.Range[uint32]
    50  	IncludeAndroidUser       []int
    51  	IncludePackage           []string
    52  	ExcludePackage           []string
    53  	InterfaceMonitor         DefaultInterfaceMonitor
    54  	TableIndex               int
    55  	FileDescriptor           int
    56  	Logger                   logger.Logger
    57  }
    58  
    59  func CalculateInterfaceName(name string) (tunName string) {
    60  	if runtime.GOOS == "darwin" {
    61  		tunName = "utun"
    62  	} else if name != "" {
    63  		tunName = name
    64  	} else {
    65  		tunName = "tun"
    66  	}
    67  	interfaces, err := net.Interfaces()
    68  	if err != nil {
    69  		return
    70  	}
    71  	var tunIndex int
    72  	for _, netInterface := range interfaces {
    73  		if strings.HasPrefix(netInterface.Name, tunName) {
    74  			index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
    75  			if parseErr == nil {
    76  				tunIndex = int(index) + 1
    77  			}
    78  		}
    79  	}
    80  	tunName = F.ToString(tunName, tunIndex)
    81  	return
    82  }