gpt4 book ai didi

macos - 在 MacOS 上使用 Go 1.5 创建 RAW 数据包

转载 作者:IT王子 更新时间:2023-10-29 00:46:19 27 4
gpt4 key购买 nike

我正在尝试为我正在使用的测试工具做一些基本的数据包制作,但我似乎无法让数据包制作工作(我在 OSX 上使用 Go 1.5 并以 root 身份运行。)

我正在使用以下代码 ( taken from here ) 尝试创建一个 ICMP 数据包,但是当我尝试在 IP header 中指定特定选项时,它似乎不起作用。此外,当我在 wireshark 中查看此数据包时,它显示为协议(protocol) 255(未知)。

我读到在 Linux 系统上你可以使用 AF_PACKET 但在 OSX 系统上你需要使用 BPF,但是我发现的示例代码使用的是“syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)”而且我不确定如何开始使用 BPF。我还看到有人尝试使用 gopacket 而不是 x/net/ipv4 包。

package main

import (
"golang.org/x/net/ipv4"
"net"
"syscall"
)

func main() {
var err error
fd, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)

addr := syscall.SockaddrInet4{
Port: 0,
Addr: [4]byte{127, 0, 0, 1},
}
p := pkt()

_ = syscall.Sendto(fd, p, 0, &addr)
}

func pkt() []byte {
h := ipv4.Header{
Version: 4,
Len: 20,
TOS: 0,
TotalLen: 85, // I can not seem to change this
ID: 2, // I can not seem to change this
TTL: 64, // I can not seem to change this
Protocol: 1, // ICMP, This does not seem to work
Dst: net.IPv4(127, 0, 0, 1),
}

icmp := []byte{
8, // type: echo request
0, // code: not used by echo request
0, // checksum (16 bit), we fill in below
0,
0, // identifier (16 bit). zero allowed.
0,
0, // sequence number (16 bit). zero allowed.
0,
0xC0, // Optional data. ping puts time packet sent here
0xDE,
}
cs := csum(icmp)
icmp[2] = byte(cs)
icmp[3] = byte(cs >> 8)

out, _ := h.Marshal()

return append(out, icmp...)
}

func csum(b []byte) uint16 {
var s uint32
for i := 0; i < len(b); i += 2 {
s += uint32(b[i+1])<<8 | uint32(b[i])
}
// add back the carry
s = s>>16 + s&0xffff
s = s + s>>16
return uint16(^s)
}

如果在数据从 pkt() 返回后,我在 Main() 中打印出包含数据包数据的 p 变量,它看起来是正确的:

DEBUG: (decimal) [69 0 60 0 0 0 0 0 64 1 0 0 0 0 0 0 127 0 0 1 8 0 55 33 0 0 0 0 192 222]
DEBUG: (hex) 45 0 3c 0 0 0 0 0 40 1 0 0 0 0 0 0 7f 0 0 1 8 0 37 21 0 0 0 0 c0 de

并且您可以看到协议(protocol)在第 10 个字节中设置为“1”。但是当我们在 wireshark 中查看这个数据包时,它看起来像:

wireshark screen shot

最佳答案

好的,我现在可以让它在 OS X 上运行了。您需要确保正在设置 IP_HDRINCL 套接字选项 syscall.SetsockoptInt(s, syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1) 然后您需要小心构建包。一个让我抓了很长时间的技巧是,出于某种原因,Sendto OS X/BSD want the IP length in host byte order ,在我的例子中是 LittleEndian,而不是典型的网络顺序 BigEndian。如果您查看这段代码(我只是自己构建了 IP header ,您可以用另一种方式构建它)它会按预期运行。

package main

import (
"encoding/binary"
"fmt"
"syscall"
)

func main() {
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
if err != nil {
panic(err)
}

err = syscall.SetsockoptInt(s, syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
if err != nil {
panic(err)
}
addr := syscall.SockaddrInet4{Addr: [4]byte{127, 0, 0, 1}}

data := makepacket()

for _, v := range data {
if v == 0 {
fmt.Printf("00 ")
continue
} else if v < 0xf {
fmt.Printf("0%x ", v)
continue
}
fmt.Printf("%x ", v)
}
fmt.Printf("\n")
err = syscall.Sendto(s, data, 0, &addr)
if err != nil {
panic(err)
}
}

func makepacket() []byte {
icmp := []byte{
8, // type: echo request
0, // code: not used by echo request
0, // checksum (16 bit), we fill in below
0,
0, // identifier (16 bit). zero allowed.
0,
0, // sequence number (16 bit). zero allowed.
0,
0xC0, // Optional data. ping puts time packet sent here
0xDE,
}
cs := csum(icmp)
icmp[2] = byte(cs)
icmp[3] = byte(cs >> 8)

buf := []byte{0x45, 0x00, 0x00, 0x00, 0x95, 0x13, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x7f, 0x00, 0x0
0, 0x01, 0x7f, 0x00, 0x00, 0x01}
binary.LittleEndian.PutUint16(buf[2:4], uint16(len(icmp) + len(buf)))
return append(buf, icmp...)
}

func csum(b []byte) uint16 {
var s uint32
for i := 0; i < len(b); i += 2 {
s += uint32(b[i+1])<<8 | uint32(b[i])

此代码在 # tcpdump -X -i lo0

中为我提供了此输出
20:05:24.016465 IP localhost > localhost: ICMP echo request, id 0, seq 0, length 10
0x0000: 4500 001e 9513 0000 4001 0000 7f00 0001 E.......@.......
0x0010: 7f00 0001 0800 3721 0000 0000 c0de ......7!......
20:05:24.016495 IP localhost > localhost: ICMP echo reply, id 0, seq 0, length 10
0x0000: 4500 001e 3e4f 0000 4001 0000 7f00 0001 E...>O..@.......
0x0010: 7f00 0001 0000 3f21 0000 0000 c0de ......?!......

关于macos - 在 MacOS 上使用 Go 1.5 创建 RAW 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32575558/

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