Networking Golang-获取网络接口的混杂模式状态
我使用下面的Go代码获取有关网络接口的一些信息。关于如何获得每个接口的混杂模式状态,有什么建议吗Networking Golang-获取网络接口的混杂模式状态,networking,go,interface,promiscuous-mode,Networking,Go,Interface,Promiscuous Mode,我使用下面的Go代码获取有关网络接口的一些信息。关于如何获得每个接口的混杂模式状态,有什么建议吗 type Iface struct { Name string `json:"name"` Status string `json:"status"` Multicast bool `json:"multicast"` Broadcast bool `json:"broadcast"` } func (c *InterfacesController) Get
type Iface struct {
Name string `json:"name"`
Status string `json:"status"`
Multicast bool `json:"multicast"`
Broadcast bool `json:"broadcast"`
}
func (c *InterfacesController) GetInterfaces() {
interfaces, err := net.Interfaces()
if err != nil {
fmt.Println(err)
return
}
var ifaceset []Iface
var ifc Iface
for _, i := range interfaces {
ifc.Name = i.Name
if strings.Contains(i.Flags.String(), "up") {
ifc.Status = "UP"
} else {
ifc.Status = "DOWN"
}
if strings.Contains(i.Flags.String(), "multicast") {
ifc.Multicast = true
} else {
ifc.Multicast = false
}
if strings.Contains(i.Flags.String(), "broadcast") {
ifc.Broadcast = true
} else {
ifc.Broadcast = false
}
ifaceset = append(ifaceset, ifc)
}
}
Go似乎没有一种跨平台的方式来检查PROMISC标志(我甚至不能确定windows是否存在这样的标志)。下面是一种在linux上获取它的方法,我猜你是在:
package main
import (
"fmt"
"net"
"os"
"syscall"
"unsafe"
)
func GetPromiscuous(i net.Interface) (bool, error) {
tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
if err != nil {
return false, os.NewSyscallError("netlinkrib", err)
}
msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil {
return false, os.NewSyscallError("parsenetlinkmessage", err)
}
loop:
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
break loop
case syscall.RTM_NEWLINK:
ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
if ifim.Index == int32(i.Index) {
return (ifim.Flags & syscall.IFF_PROMISC) != 0, nil
}
}
}
return false, os.ErrNotExist
}
func main() {
ints, err := net.Interfaces()
if err != nil {
panic(err)
}
for _, i := range ints {
p, err := GetPromiscuous(i)
if err != nil {
panic(err)
}
fmt.Println(i.Name, p)
}
}
这是基于标准库中的函数。它用于获取接口的标志。除非您想使用自己的syscall.NetlinkRIB
功能,否则此代码将始终提取每个网络设备的信息,并过滤掉请求的信息
使用cgo和ioctl是获得所需标志的一种不那么神奇的方法:
package main
/*
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
bool is_promisc(char *name) {
int s = socket(AF_INET, SOCK_STREAM, 0);
struct ifreq *i = malloc(sizeof *i);
strncpy((char *)&(i->ifr_name), name, IFNAMSIZ);
ioctl(s, SIOCGIFFLAGS, i);
bool p = (i->ifr_flags & IFF_PROMISC) != 0;
free(i);
return p;
}
*/
import "C"
import (
"fmt"
"net"
)
func GetPromiscuous(i net.Interface) (bool, error) {
set, err := C.is_promisc(C.CString(i.Name))
return bool(set), err
}
func main() {
ints, err := net.Interfaces()
if err != nil {
panic(err)
}
for _, i := range ints {
p, err := GetPromiscuous(i)
if err != nil {
panic(err)
}
fmt.Println(i.Name, p)
}
}
主程序包
/*
#包括
#包括
#包括
#包括
#包括
#包括
bool is_promisc(字符*名称){
int s=套接字(AF_INET,SOCK_STREAM,0);
结构ifreq*i=malloc(sizeof*i);
strncpy((char*)&(i->ifr_name)、name、IFNAMSIZ);
ioctl(s,SIOCGIFFLAGS,i);
boolp=(i->ifr\u标志和IFF\u混杂)!=0;
免费(i);
返回p;
}
*/
输入“C”
进口(
“fmt”
“净额”
)
func GetPromiscuous(i net.Interface)(bool,error){
set,err:=C.is_promisc(C.CString(i.Name))
返回布尔值(设置),错误
}
func main(){
ints,err:=net.Interfaces()
如果错误!=零{
恐慌(错误)
}
对于u,i:=范围整数{
p、 错误:=get滥交(i)
如果错误!=零{
恐慌(错误)
}
fmt.Println(i.Name,p)
}
}
最后一点需要注意的是,无论哪种方式,都不一定能正确地告诉您接口实际上是否处于混杂模式。有关更多详细信息,请参阅
据我所知,使用netlink路由应该可以正常工作,但另一篇帖子说我们应该检查滥交数量。如果有人知道怎么做,请告诉我,因为我找不到怎么做。关于这件事的讨论已经结束
我认为只要你不做任何疯狂的网络工作(网桥、vlan接口、macvtap等),这两种方法中的任何一种都会起作用。如果你使用iproute2工具在接口上打开和关闭promisc,代码肯定会起作用。工作环境是Ubuntu,我使用了
ifconfig
命令并检查了每个接口的详细信息,以查看它是否包含单词PROMISC
。大概是这样的:
//
// get the interfaces
//
interfaces, err := net.Interfaces()
//
// run the ifconfig command
//
out, err := exec.Command("/bin/sh", "-c", "ifconfig").Output()
var ifc Iface
var ifaceset []Iface
//
// split the output to handle each interface separately
//
var ifaceDetails = strings.Split(string(out), "\n\n")
//
// iterate interfaces
//
for _, i := range interfaces {
ifc.Name = i.Name
if strings.Contains(i.Flags.String(), "up") {
ifc.Status = "UP"
} else {
ifc.Status = "DOWN"
}
if strings.Contains(i.Flags.String(), "multicast") {
ifc.Multicast = true
} else {
ifc.Multicast = false
}
if strings.Contains(i.Flags.String(), "broadcast") {
ifc.Broadcast = true
} else {
ifc.Broadcast = false
}
//
// try to find the word PROMISC to check if it is UP
//
for _, ifdetails := range ifaceDetails {
if strings.Contains(ifdetails, i.Name) {
if strings.Contains(ifdetails, "PROMISC") {
ifc.Promisc = true
} else {
ifc.Promisc = false
}
}
}
ifaceset = append(ifaceset, ifc)
}
}