नेटवर्क इंटरफेस के बारे में कुछ जानकारी प्राप्त करने के लिए मैं निम्नलिखित गो कोड का उपयोग करता हूं। कैसे मैं प्रत्येक इंटरफ़ेस के लिए उचित मोड की स्थिति प्राप्त करने में सक्षम हो जाएगा पर कोई सुझाव?
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 जवाब
काम करने का माहौल उबंटू है, मैंने 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)
}
}
ऐसा प्रतीत नहीं होता है कि गो के पास 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 टूल का उपयोग करते हैं।
संबंधित सवाल
नए सवाल
networking
अधिकांश प्रोग्रामिंग प्रश्नों के लिए [नेटवर्क-प्रोग्रामिंग] टैग का उपयोग करें। गैर-प्रोग्रामिंग नेटवर्किंग प्रश्न विषय से बाहर हैं और इसके बजाय नेटवर्क इंजीनियरिंग, सुपर उपयोगकर्ता या सर्वर दोष पर पूछा जाना चाहिए। यह टैग केवल सॉफ्टवेयर विकास के समर्थन में अद्वितीय नेटवर्किंग आवश्यकताओं से संबंधित प्रश्नों के लिए उपयुक्त है।