我想编写代理服务器,代理服务器更改数据包的IP /端口并发出修改。
package main
import (
"encoding/hex"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"fmt"
"net"
)
func main() {
packetData := []byte{
69, 0, 0, 63, 64, 237, 64, 0, 64, 6, 74, 221, 192,
168, 1, 90, 52, 85, 184, 151, 141, 230, 0, 80,
174, 147, 86, 192, 18, 107, 243, 149, 128, 24,
0, 229, 92, 65, 0, 0, 1, 1, 8, 10, 22, 138, 85, 109,
48, 16, 32, 253, 49, 50, 51, 52, 53, 54, 55, 56,
57, 48, 10,
}
fmt.Println("Hex dump of real IP packet taken as input:\n")
fmt.Println(hex.Dump(packetData))
packet := gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.Default)
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip := ipLayer.(*layers.IPv4)
dst := ip.DstIP.String()
src := ip.SrcIP.String()
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp := tcpLayer.(*layers.TCP)
dst = fmt.Sprintf("%s:%d", dst, tcp.DstPort)
src = fmt.Sprintf("%s:%d", src, tcp.SrcPort)
fmt.Printf("From %s to %s\n\n", src, dst)
ip.DstIP = net.ParseIP("8.8.8.8")
options := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
newBuffer := gopacket.NewSerializeBuffer()
gopacket.SerializeLayers(newBuffer, options,
ip,
tcp,
)
outgoingPacket := newBuffer.Bytes()
fmt.Println("Hex dump of go packet serialization output:\n")
fmt.Println(hex.Dump(outgoingPacket))
}
}
}
Hex dump of real IP packet taken as input:
00000000 45 00 00 3f 40 ed 40 00 40 06 4a dd c0 a8 01 5a |E..?@.@.@.J....Z|
00000010 34 55 b8 97 8d e6 00 50 ae 93 56 c0 12 6b f3 95 |4U.....P..V..k..|
00000020 80 18 00 e5 5c 41 00 00 01 01 08 0a 16 8a 55 6d |....\A........Um|
00000030 30 10 20 fd 31 32 33 34 35 36 37 38 39 30 0a |0. .1234567890.|
From 192.168.1.90:36326 to 52.85.184.151:80
Hex dump of go packet serialization output:
00000000 8d e6 00 50 ae 93 56 c0 12 6b f3 95 80 18 00 e5 |...P..V..k......|
00000010 00 00 00 00 01 01 08 0a 16 8a 55 6d 30 10 20 fd |..........Um0. .|
第二个十六进制转储必须以45开头(大多数IPv4数据包以45开头,其中4是协议版本)。除了一个已更改的IP地址,TCP校验和和大小值之外,第二个hexdump必须与许多细节中的第一个相同。第二个十六进制转储必须包含有效负载1234567890\n
。
答案 0 :(得分:2)
首先,始终检查返回的错误 - 这是您的反馈:
err := gopacket.SerializePacket(newBuffer, options, packet)
// OR
err := gopacket.SerializeLayers(newBuffer, options,
ip,
tcp,
)
// THEN
if err != nil {
panic(err)
}
从上面的代码中您将获得:TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use
然后,解决方案是使用tcp.SetNetworkLayerForChecksum(ip)
和最终工作代码:
package main
import (
"encoding/hex"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"fmt"
"net"
)
func main() {
packetData := []byte{
69, 0, 0, 63, 64, 237, 64, 0, 64, 6, 74, 221, 192,
168, 1, 90, 52, 85, 184, 151, 141, 230, 0, 80,
174, 147, 86, 192, 18, 107, 243, 149, 128, 24,
0, 229, 92, 65, 0, 0, 1, 1, 8, 10, 22, 138, 85, 109,
48, 16, 32, 253, 49, 50, 51, 52, 53, 54, 55, 56,
57, 48, 10,
}
fmt.Println("Hex dump of real IP packet taken as input:\n")
fmt.Println(hex.Dump(packetData))
packet := gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.Default)
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip := ipLayer.(*layers.IPv4)
dst := ip.DstIP.String()
src := ip.SrcIP.String()
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp := tcpLayer.(*layers.TCP)
dst = fmt.Sprintf("%s:%d", dst, tcp.DstPort)
src = fmt.Sprintf("%s:%d", src, tcp.SrcPort)
fmt.Printf("From %s to %s\n\n", src, dst)
ip.DstIP = net.ParseIP("8.8.8.8")
options := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
tcp.SetNetworkLayerForChecksum(ip)
newBuffer := gopacket.NewSerializeBuffer()
err := gopacket.SerializePacket(newBuffer, options, packet)
if err != nil {
panic(err)
}
outgoingPacket := newBuffer.Bytes()
fmt.Println("Hex dump of go packet serialization output:\n")
fmt.Println(hex.Dump(outgoingPacket))
}
}
}
Hex dump of real IP packet taken as input:
00000000 45 00 00 3f 40 ed 40 00 40 06 4a dd c0 a8 01 5a |E..?@.@.@.J....Z|
00000010 34 55 b8 97 8d e6 00 50 ae 93 56 c0 12 6b f3 95 |4U.....P..V..k..|
00000020 80 18 00 e5 5c 41 00 00 01 01 08 0a 16 8a 55 6d |....\A........Um|
00000030 30 10 20 fd 31 32 33 34 35 36 37 38 39 30 0a |0. .1234567890.|
From 192.168.1.90:36326 to 52.85.184.151:80
Hex dump of go packet serialization output:
00000000 45 00 00 3f 40 ed 40 00 40 06 27 ba c0 a8 01 5a |E..?@.@.@.'....Z|
00000010 08 08 08 08 8d e6 00 50 ae 93 56 c0 12 6b f3 95 |.......P..V..k..|
00000020 80 18 00 e5 39 1e 00 00 01 01 08 0a 16 8a 55 6d |....9.........Um|
00000030 30 10 20 fd 31 32 33 34 35 36 37 38 39 30 0a |0. .1234567890.|
如您所见08 08 08 08
是一个新的IP并且有效负载1234567890\n
也被保留,IP数据包通常以45开头。