netlink

package module
v0.0.0-...-0406035 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 5, 2016 License: MIT Imports: 5 Imported by: 0

README

Build Status GoDoc

The netlink package provides a communication protocol which allows process exchanging information no matter ther are in user or kernel space.

Most kernal's process need communicate with user's process in Linux, but traditional Unix's IPC (pipe, message queue, shared memory and singal) can not offer a strong support for the communication between user's process and kernel. Linux provides a lot other methods which allow user's process can communicate with kernel, but they are very hard to use. To make these method easier to user for user, especially for Operational Engineer is the reason why we develop netlink.

Compared with native method, netlink has following advantages:

  • The prerequistie of using netlink is just adding a new type in include/linux/netlink.h
  • nektlink is asynchronous. An instance will not be blocked after sending messages. The messages is actually saved in socket's messages buffer.
  • netlink is modularizeed. netlink'application and kernel parts are independent. They do not have any compile dependency. But system call does. Whenever a new system all want to be used. It has to be compiled statically into kernel.
  • netlink supports multicast. Kernel modules or process can pass messages into multiple netlink group.
  • netlink can be called from kernel, unlike ioctl.
  • netlink uses standard socket API, hence it is pretty simple to use unlike system call or iotcl. But these traditional protocol can not give enough support of the communication between process(user space) and kernel. Linux provides a lot of methods to fix such problem, but they are hard to learn. A new protocol netlink is easy to learn.

netlink only provides basic communication protocol between user's process and kernel's process. These specific tasks are based on the subprotocol in netlink. Additionally, inside Linux's kernel, it already has a protocol which is:

#define NETLINK_ROUTE       0   /* Routing/device hook              */
#define NETLINK_UNUSED      1   /* Unused number                */
#define NETLINK_USERSOCK    2   /* Reserved for user mode socket protocols  */
#define NETLINK_FIREWALL    3   /* Unused number, formerly ip_queue     */
#define NETLINK_SOCK_DIAG   4   /* socket monitoring                */
#define NETLINK_NFLOG       5   /* netfilter/iptables ULOG */
#define NETLINK_XFRM        6   /* ipsec */
#define NETLINK_SELINUX     7   /* SELinux event notifications */
#define NETLINK_ISCSI       8   /* Open-iSCSI */
#define NETLINK_AUDIT       9   /* auditing */
#define NETLINK_FIB_LOOKUP  10  
#define NETLINK_CONNECTOR   11
#define NETLINK_NETFILTER   12  /* netfilter subsystem */
#define NETLINK_IP6_FW      13
#define NETLINK_DNRTMSG     14  /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT  15  /* Kernel messages to userspace */
#define NETLINK_GENERIC     16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT   18  /* SCSI Transports */
#define NETLINK_ECRYPTFS    19
#define NETLINK_RDMA        20
#define NETLINK_CRYPTO      21  /* Crypto layer */
#define NETLINK_INET_DIAG   NETLINK_SOCK_DIAG
user space

If you plan use netlink in user space, then you should consider standard socker API. For creating a new netlink sockert, user need use the following arguments to call socker():

socket(AF_NETLINK, SOCK_RAW, netlink_type)

You can find more details here

kernel space

Any kernel's module wants to use netlink(in Linux, not this project) need to include header file linux/netlink.h. Compared with the usage of netlink, kernel has to use particular API defined in netlink. For now, netlink alraedy implemented a generic protocol NETLINK_GENERIC which reduces the extra work.

example
func (c *ExecCollector) prepareSocket() (*netlink.NetlinkSocket, error) {
	ns, err := netlink.NewNetlinkSocket(netlink.CONNECTOR, netlink.CN_IDX_PROC)
	if err != nil {
		return nil, fmt.Errorf("create netlink socket: %v", err)
	}
	req := netlink.NewNetlinkRequest()
	{
		msg := netlink.NewCnMsg()
		req.AddData(msg)
		op := netlink.PROC_CN_MCAST_LISTEN
		req.AddData(&op)
	}
	err = ns.Send(req)
	if err != nil {
		return nil, fmt.Errorf("Exec: %v", err)
	}
	go func() {
		<-c.shutdown
		ns.Close()
	}()
	return ns, nil
}

future work

  • need add all test for this project

miscellaneous

more information here

Documentation

Index

Constants

View Source
const (
	TCP_ESTABLISHED = iota
	TCP_SYN_SENT
	TCP_SYN_RECV
	TCP_FIN_WAIT1
	TCP_FIN_WAIT2
	TCP_TIME_WAIT
	TCP_CLOSE
	TCP_CLOSE_WAIT
	TCP_LAST_ACK
	TCP_LISTEN
	TCP_CLOSING
)

netinet/tcp.h

View Source
const (
	SOCK_DIAG_BY_FAMILY = 20 // linux/sock_diag.h
)
View Source
const (
	SizeofInetDiagReqV2 = 0x38
)
View Source
const (
	TCP_ALL = 0xFFF
)

Variables

View Source
var DiagFamilyMap = map[uint8]string{
	syscall.AF_INET:  "tcp",
	syscall.AF_INET6: "tcp6",
}
View Source
var TcpStatesMap = map[uint8]string{
	TCP_ESTABLISHED: "established",
	TCP_SYN_SENT:    "syn_sent",
	TCP_SYN_RECV:    "syn_recv",
	TCP_FIN_WAIT1:   "fin_wait1",
	TCP_FIN_WAIT2:   "fin_wait2",
	TCP_TIME_WAIT:   "time_wait",
	TCP_CLOSE:       "close",
	TCP_CLOSE_WAIT:  "close_wait",
	TCP_LAST_ACK:    "last_ack",
	TCP_LISTEN:      "listen",
	TCP_CLOSING:     "closing",
}

Functions

func NewInetDiagRequest

func NewInetDiagRequest() *nl.NetlinkRequest

Types

type InetDiagMsg

type InetDiagMsg struct {
	IDiagFamily  uint8
	IDiagState   uint8
	IDiagTimer   uint8
	IDiagRetrans uint8
	Id           InetDiagSockId
	IDiagExpires uint32
	IDiagRqueue  uint32
	IDiagWqueue  uint32
	IDiagUid     uint32
	IDiagInode   uint32
}

func ParseInetDiagMsg

func ParseInetDiagMsg(data []byte) *InetDiagMsg

func (*InetDiagMsg) String

func (msg *InetDiagMsg) String() string

type InetDiagReqV2

type InetDiagReqV2 struct {
	SDiagFamily   uint8
	SDiagProtocol uint8
	IDiagExt      uint8
	Pad           uint8
	IDiagStates   uint32
	Id            InetDiagSockId
}

func NewInetDiagReqV2

func NewInetDiagReqV2(family, protocol uint8, states uint32) *InetDiagReqV2

func (*InetDiagReqV2) Len

func (req *InetDiagReqV2) Len() int

func (*InetDiagReqV2) Serialize

func (req *InetDiagReqV2) Serialize() []byte

type InetDiagSockId

type InetDiagSockId struct {
	IDiagSPort  be16
	IDiagDPort  be16
	IDiagSrc    [4]be32
	IDiagDst    [4]be32
	IDiagIf     uint32
	IDiagCookie [2]uint32
}

linux/inet_diag.h

func (*InetDiagSockId) DstIP

func (id *InetDiagSockId) DstIP() net.IP

func (*InetDiagSockId) DstIPv4

func (id *InetDiagSockId) DstIPv4() net.IP

func (*InetDiagSockId) DstIPv6

func (id *InetDiagSockId) DstIPv6() net.IP

func (*InetDiagSockId) DstPort

func (id *InetDiagSockId) DstPort() int

func (*InetDiagSockId) SrcIP

func (id *InetDiagSockId) SrcIP() net.IP

func (*InetDiagSockId) SrcIPv4

func (id *InetDiagSockId) SrcIPv4() net.IP

func (*InetDiagSockId) SrcIPv6

func (id *InetDiagSockId) SrcIPv6() net.IP

func (*InetDiagSockId) SrcPort

func (id *InetDiagSockId) SrcPort() int

func (*InetDiagSockId) String

func (id *InetDiagSockId) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL