package  netimport  (	"errors" 	"internal/itoa" 	"sync" 	"time" 	_  "unsafe" )var  (	errInvalidInterface         = errors .New ("invalid network interface" )	errInvalidInterfaceIndex    = errors .New ("invalid network interface index" )	errInvalidInterfaceName     = errors .New ("invalid network interface name" )	errNoSuchInterface          = errors .New ("no such network interface" )	errNoSuchMulticastInterface = errors .New ("no such multicast network interface" ))type  Interface  struct  {	Index        int           	MTU          int           	Name         string        	HardwareAddr HardwareAddr  	Flags        Flags         }type  Flags  uint const  (	FlagUp            Flags  = 1  << iota  	FlagBroadcast                       	FlagLoopback                        	FlagPointToPoint                    	FlagMulticast                       	FlagRunning                         )var  flagNames = []string {	"up" ,	"broadcast" ,	"loopback" ,	"pointtopoint" ,	"multicast" ,	"running" ,}func  (f  Flags ) String () string  {	s  := "" 	for  i , name  := range  flagNames  {		if  f &(1 <<uint (i )) != 0  {			if  s  != ""  {				s  += "|" 			}			s  += name 		}	}	if  s  == ""  {		s  = "0" 	}	return  s }func  (ifi  *Interface ) Addrs () ([]Addr , error ) {	if  ifi  == nil  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : errInvalidInterface }	}	ifat , err  := interfaceAddrTable (ifi )	if  err  != nil  {		err  = &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	return  ifat , err }func  (ifi  *Interface ) MulticastAddrs () ([]Addr , error ) {	if  ifi  == nil  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : errInvalidInterface }	}	ifat , err  := interfaceMulticastAddrTable (ifi )	if  err  != nil  {		err  = &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	return  ifat , err }func  Interfaces Interface , error ) {	ift , err  := interfaceTable (0 )	if  err  != nil  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	if  len (ift ) != 0  {		zoneCache .update (ift , false )	}	return  ift , nil }func  InterfaceAddrs Addr , error ) {	ifat , err  := interfaceAddrTable (nil )	if  err  != nil  {		err  = &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	return  ifat , err }func  InterfaceByIndex index  int ) (*Interface , error ) {	if  index  <= 0  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : errInvalidInterfaceIndex }	}	ift , err  := interfaceTable (index )	if  err  != nil  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	ifi , err  := interfaceByIndex (ift , index )	if  err  != nil  {		err  = &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	return  ifi , err }func  interfaceByIndex(ift  []Interface , index  int ) (*Interface , error ) {	for  _ , ifi  := range  ift  {		if  index  == ifi .Index  {			return  &ifi , nil 		}	}	return  nil , errNoSuchInterface }func  InterfaceByName name  string ) (*Interface , error ) {	if  name  == ""  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : errInvalidInterfaceName }	}	ift , err  := interfaceTable (0 )	if  err  != nil  {		return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : err }	}	if  len (ift ) != 0  {		zoneCache .update (ift , false )	}	for  _ , ifi  := range  ift  {		if  name  == ifi .Name  {			return  &ifi , nil 		}	}	return  nil , &OpError {Op : "route" , Net : "ip+net" , Source : nil , Addr : nil , Err : errNoSuchInterface }}type  ipv6ZoneCache struct  {	sync .RWMutex                 	lastFetched  time .Time       	toIndex      map [string ]int  	toName       map [int ]string  }var  zoneCache = ipv6ZoneCache {	toIndex : make (map [string ]int ),	toName :  make (map [int ]string ),}func  (zc  *ipv6ZoneCache ) update (ift  []Interface , force  bool ) (updated  bool ) {	zc .Lock ()	defer  zc .Unlock ()	now  := time .Now ()	if  !force  && zc .lastFetched .After (now .Add (-60 *time .Second )) {		return  false 	}	zc .lastFetched  = now 	if  len (ift ) == 0  {		var  err  error 		if  ift , err  = interfaceTable (0 ); err  != nil  {			return  false 		}	}	zc .toIndex  = make (map [string ]int , len (ift ))	zc .toName  = make (map [int ]string , len (ift ))	for  _ , ifi  := range  ift  {		if  ifi .Name  != ""  {			zc .toIndex [ifi .Name ] = ifi .Index 			if  _ , ok  := zc .toName [ifi .Index ]; !ok  {				zc .toName [ifi .Index ] = ifi .Name 			}		}	}	return  true }func  (zc  *ipv6ZoneCache ) name (index  int ) string  {	if  index  == 0  {		return  "" 	}	updated  := zoneCache .update (nil , false )	zoneCache .RLock ()	name , ok  := zoneCache .toName [index ]	zoneCache .RUnlock ()	if  !ok  && !updated  {		zoneCache .update (nil , true )		zoneCache .RLock ()		name , ok  = zoneCache .toName [index ]		zoneCache .RUnlock ()	}	if  !ok  { 		name  = itoa .Uitoa (uint (index ))	}	return  name }func  (zc  *ipv6ZoneCache ) index (name  string ) int  {	if  name  == ""  {		return  0 	}	updated  := zoneCache .update (nil , false )	zoneCache .RLock ()	index , ok  := zoneCache .toIndex [name ]	zoneCache .RUnlock ()	if  !ok  && !updated  {		zoneCache .update (nil , true )		zoneCache .RLock ()		index , ok  = zoneCache .toIndex [name ]		zoneCache .RUnlock ()	}	if  !ok  { 		index , _, _ = dtoi (name )	}	return  index } The pages are generated with Golds v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .