我正在寻找一种使用go语言发送数据包的方法,这使我能够查看和设置TTL和其他低级别数据包字段(我不需要修改以太网头文件只需ip和UDP头文件)。我试图在下面的代码中制作和发送我自己的数据包。
运行以下代码时,接收方不会收到任何消息。任何人都可以。)警告我在此代码中所做的任何错误或b。)建议使用golang发送udp数据的另一种方法,同时保留对ip和amp;的访问权限。 udp标题?
(我删除了mac地址,需要更换它们才能运行此代码)
package main
import (
"syscall"
"log"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"fmt"
"encoding/hex"
"encoding/json"
"net"
)
type NameTag struct {
Name string `json:"name"`
}
func main() {
var err error
fd, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_UDP)
if e != nil {
fmt.Println("Problem @ location 1")
}
addr := syscall.SockaddrInet4{
Port: 27289,
Addr: [4]byte{127, 0, 0, 1},
}
p := pkt()
err = syscall.Sendto(fd, p, 0, &addr)
if err != nil {
log.Fatal("Sendto:", err)
}
}
func pkt() []byte {
sb := gopacket.NewSerializeBuffer()
nt := NameTag{"Paul"}
b, _ := json.Marshal(nt)
pld := gopacket.Payload(b)
l := uint16(len(pld))
udp := layers.UDP{
SrcPort: 27289,
DstPort: 27288,
Length: l + 8,
Checksum: 0,
}
l = l + 8
ip := layers.IPv4{
Version: 0x4,
IHL: 5,
Length: 20 + l,
TTL: 255,
Flags: 0x40,
FragOffset: 0,
Checksum: 0,
Protocol: syscall.IPPROTO_UDP,
DstIP: net.IPv4(127, 0, 0, 1),
SrcIP: net.IPv4(127, 0, 0, 1),
}
l = l + 20
eth := layers.Ethernet{
EthernetType: layers.EthernetTypeIPv4,
SrcMAC: net.HardwareAddr{
0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
},
DstMAC: net.HardwareAddr{
0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
},
}
fmt.Println(pld.SerializeTo(sb, gopacket.SerializeOptions{}))
fmt.Println(udp.SerializeTo(sb, gopacket.SerializeOptions{}))
fmt.Println(ip.SerializeTo(sb, gopacket.SerializeOptions{}))
fmt.Println(eth.SerializeTo(sb, gopacket.SerializeOptions{}))
//Debug prints here (first line is for dump to packet validator)
fmt.Println(hex.EncodeToString(sb.Bytes()))
fmt.Println(sb.Bytes())
return sb.Bytes()
}
package main
import (
"syscall"
"os"
"fmt"
)
func main() {
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_UDP)
if err != nil {
fmt.Println(err)
return
}
sa:= &syscall.SockaddrInet4{
Addr: [4]byte{127,0,0,1},
Port:27288,
}
e := syscall.Bind(fd, sa)
if e != nil {
fmt.Println("problems @ location 1")
}
f := os.NewFile(uintptr(fd), fmt.Sprintf("fd%d", fd))
fmt.Println("Entering main loop")
for {
fmt.Println("In loop")
buf := make([]byte, 1024)
numRead, err := f.Read(buf)
if err != nil {
fmt.Println("problems @ location 2")
}
fmt.Printf("Loop done %v\n", buf[:numRead])
}
}