func (v *vNet) getAllIPAddrs(ipv6 bool) []net.IP {
	ips := []net.IP{}
	for _, ifc := range v.interfaces {
		addrs, err := ifc.Addrs()
		if err != nil {
			continue
		}
		for _, addr := range addrs {
			var ip net.IP
			if ipNet, ok := addr.(*net.IPNet); ok {
				ip = ipNet.IP
			} else if ipAddr, ok := addr.(*net.IPAddr); ok {
				ip = ipAddr.IP
			} else {
				continue
			}
			if !ipv6 {
				if ip.To4() != nil {
					ips = append(ips, ip)
				}
			}
		}
	}
	return ips
}
caller must hold the mutex
package vnet
import (
	"encoding/binary"
	"fmt"
	"math/rand"
	"net"
	"strconv"
	"strings"
	"sync"
)
var macAddrCounter uint64 = 0xBEEFED910200
func newMACAddress() net.HardwareAddr {
	b := make([]byte, 8)
	binary.BigEndian.PutUint64(b, macAddrCounter)
	macAddrCounter++
	return b[2:]
}
type vNet struct {
	interfaces []*Interface  
	staticIPs  []net.IP      
	router     *Router       
	udpConns   *udpConnMap   
	mutex      sync.RWMutex
}
func (v *vNet) _getInterfaces() ([]*Interface, error) {
	if len(v.interfaces) == 0 {
		return nil, fmt.Errorf("no interface is available")
	}
	return v.interfaces, nil
}
func (v *vNet) getInterfaces() ([]*Interface, error) {
	v.mutex.RLock()
	defer v.mutex.RUnlock()
	return v._getInterfaces()
}
func (v *vNet) _getInterface(ifName string) (*Interface, error) {
	ifs, err := v._getInterfaces()
	if err != nil {
		return nil, err
	}
	for _, ifc := range ifs {
		if ifc.Name == ifName {
			return ifc, nil
		}
	}
	return nil, fmt.Errorf("interface %s not found", ifName)
}
func (v *vNet) getInterface(ifName string) (*Interface, error) {
	v.mutex.RLock()
	defer v.mutex.RUnlock()
	return v._getInterface(ifName)
}