Why
I want to write a proxy server, proxy server changes IP/port of a packet and emits modified.
Attempt
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))
}
}
}
Output
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. .|
What's Wrong
Second hex dump must start with 45 (most IPv4 packets start with 45, where 4 is a version of the protocol). Second hexdump must be identical to the first in many details except one IP address that was changed, TCP checksum and size values. Second hex dump must contain payload 1234567890\n
.