gpt4 book ai didi

windows - 转到 : Raw winsock

转载 作者:数据小太阳 更新时间:2023-10-29 03:05:14 24 4
gpt4 key购买 nike

我正在尝试创建一个简单的 tcp 原始 winsock,但我的 socket.Recvfrom 出现错误“不支持的套接字”,我做错了什么?

package main

import (
"golang.org/x/sys/windows"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"log"
"net"
"sync"
"os"
//~ "syscall"
"time"
"fmt"
"errors"
"unsafe"
)

const SIO_RCVALL = windows.IOC_IN | windows.IOC_VENDOR | 1

type Handle struct {
blockForever bool
device string
deviceIndex int
mu sync.Mutex
socket windows.Handle
timeout time.Duration
snaplen int32
}

const BlockForever = -time.Millisecond * 10

func main() {
var (
device string = "eth0"
Snaplen int32 = 65536
Timeout time.Duration = 30 * time.Second
)

var (
ip4 layers.IPv4
tcp layers.TCP
)

parser := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, &ip4, &tcp)
decoded := []gopacket.LayerType{}

hnd, err := OpenLive(device, Snaplen, Timeout)
if err != nil {
log.Fatal(err)
}
defer hnd.Close()

packetSource := gopacket.NewPacketSource(hnd, hnd.LinkType())

for packetData := range packetSource.Packets() {
err := parser.DecodeLayers(packetData.Data(), &decoded)

if packetData == nil || err != nil {
continue
}

for _, layerType := range decoded {
switch layerType {
case layers.LayerTypeIPv4:
log.Println(" IP4 ", ip4.SrcIP, ip4.DstIP)
case layers.LayerTypeTCP:
log.Println(tcp.TransportFlow().Src().String())
}
}
}

}

func OpenLive(device string, snaplen int32, timeout time.Duration) (handle *Handle, err error) {
p := &Handle{}
p.blockForever = timeout < 0
p.timeout = timeout
p.snaplen = snaplen

var d windows.WSAData

log.Println("Initialising Winsock...")
err = windows.WSAStartup(uint32(0x202), &d)
if err != nil {
return nil, fmt.Errorf("Error: WSAStartup - %v", err)
}
log.Println("Initialised")

//Create a RAW Socket
log.Println("Creating RAW Socket...");
fd, err := windows.Socket(windows.AF_INET, windows.SOCK_RAW, windows.IPPROTO_IP)
if err != nil {
return nil, fmt.Errorf("Error: socket - %v", err)
}
p.socket = fd
log.Println("Created.")

// Retrieve the local hostname
hostname, err := os.Hostname()

if err != nil {
return nil, fmt.Errorf("Error: Hostname() - %v", err)
}
log.Printf("\nHost name : %s \n",hostname)

//Retrieve the available IPs of the local host
log.Println("Available Network Interfaces : \n")
_ , err = windows.GetHostByName(hostname)

if err != nil {
return nil, fmt.Errorf("Error: GetHostByName() - %v", err)
}

ip4 , iFcindex, err := externalIP()
if err != nil {
return nil, fmt.Errorf("Error: getIpv4() - %v", err)
}
p.deviceIndex = iFcindex

la := new(windows.SockaddrInet4)
la.Port = int(0)

for i := 0; i < net.IPv4len; i++ {
la.Addr[i] = ip4[i]
}

if err := windows.Bind(fd, la); err != nil {
return nil, fmt.Errorf ("Error:Bind - %v", err)
}

inbuf := uint32(1)
sizebuf := uint32(unsafe.Sizeof(inbuf))
ret := uint32(0)

err = windows.WSAIoctl(fd, SIO_RCVALL , (*byte)(unsafe.Pointer(&inbuf)) ,sizebuf, nil ,0 ,&ret , nil, 0);

if err != nil {
return nil, fmt.Errorf ("Error:WSAIoctl() failed - %v", err)
}

return p, nil

}

// Close closes the underlying socket handle.
func (p *Handle) Close() {
p.mu.Lock()
defer p.mu.Unlock()

windows.Close(p.socket)
}

func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
p.mu.Lock()
data = make([]byte, 65536)
n, _, err := windows.Recvfrom(p.socket, data, 0)
log.Println(n)
if err != nil {
log.Printf("Error:Recvfrom() - %v", err)
}
ci = gopacket.CaptureInfo{Timestamp: time.Now(), CaptureLength: len(data), Length: n, InterfaceIndex: p.deviceIndex}

p.mu.Unlock()

return
}

func htons(n int) int {
return int(int16(byte(n))<<8 | int16(byte(n>>8)))
}

func externalIP() (IPBYTE []byte, ifaceIndex int ,err error) {

ifaces, err := net.Interfaces()
if err != nil {
return
}

IPBYTE = make([]byte, 4)
ifaceIndex = 0

for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
continue
}

for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
IPBYTE = ip.To4()
ifaceIndex = iface.Index
if IPBYTE == nil {
continue // not an ipv4 address
}
//~ err = nil

log.Printf("Active Network Interfaces %v : %v " ,iface.Index , ip.String())
return IPBYTE ,ifaceIndex , nil
}
}

err = errors.New("are you connected to the network?")
return
}

// LinkType returns pcap_datalink, as a layers.LinkType.
func (p *Handle) LinkType() layers.LinkType {
return layers.LinkTypeIPv4
}

最佳答案

在当前版本的Go中,错误信息是

not supported by windows

这是不言自明的。

如果您跟踪对 Recvfrom() 的调用,您会发现

func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
return 0, nil, syscall.EWINDOWS
}

也就是上面静态错误信息的返回。

关于windows - 转到 : Raw winsock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42475093/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com