नेटवर्क इंटरफेस के बारे में कुछ जानकारी प्राप्त करने के लिए मैं निम्नलिखित गो कोड का उपयोग करता हूं। कैसे मैं प्रत्येक इंटरफ़ेस के लिए उचित मोड की स्थिति प्राप्त करने में सक्षम हो जाएगा पर कोई सुझाव?

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)
  }
}
2
tgogos 26 नवम्बर 2015, 19:02

2 जवाब

सबसे बढ़िया उत्तर

काम करने का माहौल उबंटू है, मैंने 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)
}

}

2
tgogos 4 पद 2015, 09:06

ऐसा प्रतीत नहीं होता है कि गो के पास PROMISC ध्वज की जांच करने का एक क्रॉस-प्लेटफ़ॉर्म तरीका है (मुझे यह भी पता नहीं चल सकता है कि क्या खिड़कियों के लिए ऐसा ध्वज मौजूद है।) यहाँ यह लिनक्स पर पाने का एक तरीका है, जो मैं कर रहा हूँ। अनुमान लगा रहे हैं:

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)
    }
}

यह मानक लाइब्रेरी में interfaceTable फ़ंक्शन पर आधारित है। यह झंडे पाने के लिए rtnetlink का उपयोग करता है अंतरपटल। जब तक आप अपने syscall.NetlinkRIB फंक्शन को रोल नहीं करना चाहते, यह कोड हमेशा हर नेटवर्क डिवाइस के लिए जानकारी खींचेगा और अनुरोधित को फ़िल्टर करेगा।

झंडा जो आप चाहते हैं उसे पाने के लिए थोड़ा कम जादुई तरीका है कि आप कॉगो और 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)
    }

}

एक अंतिम नोट यह है कि या तो रास्ता हमेशा आपको सही ढंग से नहीं बता सकता है कि क्या इंटरफ़ेस वास्तव में प्रोमिसस मोड में है या नहीं। अधिक जानकारी के लिए इस थ्रेड को देखें।

नेटलिंक मार्ग का उपयोग करके मैं जो पढ़ रहा हूं, उसे सही तरीके से काम करना चाहिए, लेकिन एक अन्य पोस्ट में कहा गया है कि हमें उचित गणना की जांच करनी चाहिए। कृपया मुझे बताएं कि अगर कोई जानता है कि उसे कैसे करना है, क्योंकि मुझे नहीं पता कि मैं कैसे कर सकता हूं। स्टैकओवरफ़्लो प्रश्न पर मामले में अनुत्तरित है

मुझे लगता है कि इन विधियों में से कोई भी तब तक काम करेगा जब तक आप किसी भी पागल नेटवर्किंग सामान (पुल, वलन इंटरफेस, मैकवैप, आदि) को नहीं कर रहे हैं। कोड निश्चित रूप से काम करता है यदि आप इंटरफ़ेस पर चालू और बंद करने के लिए iproute2 टूल का उपयोग करते हैं।

3
Community 23 मई 2017, 11:53