package net
import (
)
func ( int) ([]Interface, error) {
, := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
if != nil {
return nil, os.NewSyscallError("netlinkrib", )
}
, := syscall.ParseNetlinkMessage()
if != nil {
return nil, os.NewSyscallError("parsenetlinkmessage", )
}
var []Interface
:
for , := range {
switch .Header.Type {
case syscall.NLMSG_DONE:
break
case syscall.RTM_NEWLINK:
:= (*syscall.IfInfomsg)(unsafe.Pointer(&.Data[0]))
if == 0 || == int(.Index) {
, := syscall.ParseNetlinkRouteAttr(&)
if != nil {
return nil, os.NewSyscallError("parsenetlinkrouteattr", )
}
= append(, *newLink(, ))
if == int(.Index) {
break
}
}
}
}
return , nil
}
const (
sysARPHardwareIPv4IPv4 = 768
sysARPHardwareIPv6IPv6 = 769
sysARPHardwareIPv6IPv4 = 776
sysARPHardwareGREIPv4 = 778
sysARPHardwareGREIPv6 = 823
)
func ( *syscall.IfInfomsg, []syscall.NetlinkRouteAttr) *Interface {
:= &Interface{Index: int(.Index), Flags: linkFlags(.Flags)}
for , := range {
switch .Attr.Type {
case syscall.IFLA_ADDRESS:
switch len(.Value) {
case IPv4len:
switch .Type {
case sysARPHardwareIPv4IPv4, sysARPHardwareGREIPv4, sysARPHardwareIPv6IPv4:
continue
}
case IPv6len:
switch .Type {
case sysARPHardwareIPv6IPv6, sysARPHardwareGREIPv6:
continue
}
}
var bool
for , := range .Value {
if != 0 {
= true
break
}
}
if {
.HardwareAddr = .Value[:]
}
case syscall.IFLA_IFNAME:
.Name = string(.Value[:len(.Value)-1])
case syscall.IFLA_MTU:
.MTU = int(*(*uint32)(unsafe.Pointer(&.Value[:4][0])))
}
}
return
}
func ( uint32) Flags {
var Flags
if &syscall.IFF_UP != 0 {
|= FlagUp
}
if &syscall.IFF_BROADCAST != 0 {
|= FlagBroadcast
}
if &syscall.IFF_LOOPBACK != 0 {
|= FlagLoopback
}
if &syscall.IFF_POINTOPOINT != 0 {
|= FlagPointToPoint
}
if &syscall.IFF_MULTICAST != 0 {
|= FlagMulticast
}
return
}
func ( *Interface) ([]Addr, error) {
, := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
if != nil {
return nil, os.NewSyscallError("netlinkrib", )
}
, := syscall.ParseNetlinkMessage()
if != nil {
return nil, os.NewSyscallError("parsenetlinkmessage", )
}
var []Interface
if == nil {
var error
, = interfaceTable(0)
if != nil {
return nil,
}
}
, := addrTable(, , )
if != nil {
return nil,
}
return , nil
}
func ( []Interface, *Interface, []syscall.NetlinkMessage) ([]Addr, error) {
var []Addr
:
for , := range {
switch .Header.Type {
case syscall.NLMSG_DONE:
break
case syscall.RTM_NEWADDR:
:= (*syscall.IfAddrmsg)(unsafe.Pointer(&.Data[0]))
if len() != 0 || .Index == int(.Index) {
if len() != 0 {
var error
, = interfaceByIndex(, int(.Index))
if != nil {
return nil,
}
}
, := syscall.ParseNetlinkRouteAttr(&)
if != nil {
return nil, os.NewSyscallError("parsenetlinkrouteattr", )
}
:= newAddr(, )
if != nil {
= append(, )
}
}
}
}
return , nil
}
func ( *syscall.IfAddrmsg, []syscall.NetlinkRouteAttr) Addr {
var bool
for , := range {
if .Attr.Type == syscall.IFA_LOCAL {
= true
break
}
}
for , := range {
if && .Attr.Type == syscall.IFA_ADDRESS {
continue
}
switch .Family {
case syscall.AF_INET:
return &IPNet{IP: IPv4(.Value[0], .Value[1], .Value[2], .Value[3]), Mask: CIDRMask(int(.Prefixlen), 8*IPv4len)}
case syscall.AF_INET6:
:= &IPNet{IP: make(IP, IPv6len), Mask: CIDRMask(int(.Prefixlen), 8*IPv6len)}
copy(.IP, .Value[:])
return
}
}
return nil
}
func ( *Interface) ([]Addr, error) {
:= parseProcNetIGMP("/proc/net/igmp", )
:= parseProcNetIGMP6("/proc/net/igmp6", )
return append(, ...), nil
}
func ( string, *Interface) []Addr {
, := open()
if != nil {
return nil
}
defer .close()
var (
[]Addr
string
)
.readLine()
:= make([]byte, IPv4len)
for , := .readLine(); ; , = .readLine() {
:= splitAtBytes(, " :\r\t\n")
if len() < 4 {
continue
}
switch {
case [0] != ' ' && [0] != '\t':
= [1]
case len([0]) == 8:
if == nil || == .Name {
for := 0; +1 < len([0]); += 2 {
[/2], _ = xtoi2([0][:+2], 0)
}
:= *(*uint32)(unsafe.Pointer(&[:4][0]))
:= &IPAddr{IP: IPv4(byte(>>24), byte(>>16), byte(>>8), byte())}
= append(, )
}
}
}
return
}
func ( string, *Interface) []Addr {
, := open()
if != nil {
return nil
}
defer .close()
var []Addr
:= make([]byte, IPv6len)
for , := .readLine(); ; , = .readLine() {
:= splitAtBytes(, " \r\t\n")
if len() < 6 {
continue
}
if == nil || [1] == .Name {
for := 0; +1 < len([2]); += 2 {
[/2], _ = xtoi2([2][:+2], 0)
}
:= &IPAddr{IP: IP{[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15]}}
= append(, )
}
}
return
}