-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
Description
Please answer these questions before submitting your issue. Thanks!
- What version of Go are you using (
go version
)?
1.6 - What operating system and processor architecture are you using (
go env
)?
Ubuntu 14.04 64bit - What did you do?
Definition ofRTNLGRP_IPV4_IFADDR = 0x5
is incorrect from syscall.go. Because C language definition of this variable is equal to#define RTMGRP_IPV4_IFADDR 0x10
according here rtnetlink.h
I cannot get syscall.RTM_NEWADD
message due to this error. I did not create runnable code since to simulate you need IP address change. However this is my code which can be executed.
package main
import (
"fmt"
"syscall"
)
func main() {
l, _ := ListenNetlink()
for {
msgs, err := l.ReadMsgs()
if err != nil {
fmt.Println("Could not read netlink: %s", err)
}
for _, m := range msgs {
if IsNewAddr(&m) {
fmt.Println("New Addr")
}
if IsDelAddr(&m) {
fmt.Println("Del Addr")
}
}
}
}
type NetlinkListener struct {
fd int
sa *syscall.SockaddrNetlink
}
func ListenNetlink() (*NetlinkListener, error) {
groups := syscall.RTNLGRP_IPV4_IFADDR
s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM,
syscall.NETLINK_ROUTE)
if err != nil {
return nil, fmt.Errorf("socket: %s", err)
}
saddr := &syscall.SockaddrNetlink{
Family: syscall.AF_NETLINK,
Pid: uint32(0),
Groups: uint32(groups),
}
err = syscall.Bind(s, saddr)
if err != nil {
return nil, fmt.Errorf("bind: %s", err)
}
return &NetlinkListener{fd: s, sa: saddr}, nil
}
func (l *NetlinkListener) ReadMsgs() ([]syscall.NetlinkMessage, error) {
defer func() {
recover()
}()
pkt := make([]byte, 2048)
n, err := syscall.Read(l.fd, pkt)
if err != nil {
return nil, fmt.Errorf("read: %s", err)
}
msgs, err := syscall.ParseNetlinkMessage(pkt[:n])
if err != nil {
return nil, fmt.Errorf("parse: %s", err)
}
return msgs, nil
}
func IsNewAddr(msg *syscall.NetlinkMessage) bool {
if msg.Header.Type == syscall.RTM_NEWADDR {
return true
}
return false
}
func IsDelAddr(msg *syscall.NetlinkMessage) bool {
if msg.Header.Type == syscall.RTM_DELADDR {
return true
}
return false
}
func IsRelevant(msg *syscall.IfAddrmsg) bool {
if msg.Scope == syscall.RT_SCOPE_UNIVERSE ||
msg.Scope == syscall.RT_SCOPE_SITE {
return true
}
return false
}
if this line "groups := syscall.RTNLGRP_IPV4_IFADDR" will be changed to groups := uint32(16)
it start working normaly.
- What did you expect to see?
RTNLGRP_IPV4_IFADDR = 0x10
in syscall.go - What did you see instead?
RTNLGRP_IPV4_IFADDR
= 0x5 in syscall.go