0

I'm writing a program that reads all packets passing through the computer running it. I wish to grab a packet (either by dst ip or src ip), then change the dstIP and TCP dstPort and put it back on the wire.

I have no problems with changing the dstIP, but how do I serialize it properly so the packet isn't malformed and gets to the destination in which I want it to go?

package main

import (
    "code.google.com/p/gopacket"
    "code.google.com/p/gopacket/layers"
    "code.google.com/p/gopacket/pcap"
    "fmt"
    "net"
)

func main() {
    if handle, err := pcap.OpenLive("wlp4s0", 1600, true, 100); err != nil {
        panic(err)
    } else {
        packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
        for packet := range packetSource.Packets() {
            if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
                fmt.Println("This is a IP packet!")
                // Get actual IP data from this layer
                ip, _ := ipLayer.(*layers.IPv4)

                //see if the source IP is what I'm expecting
                if ip.SrcIP.Equal(net.ParseIP("192.168.1.66")) {
                    //change the dst IP to something 192.168.1.65
                    ip.DstIP = net.ParseIP("192.168.1.65")

                    // create a buffer to serialize to
                    buf := gopacket.NewSerializeBuffer()
                    //no options
                    opts := gopacket.SerializeOptions{}

                    //serialize the packet
                    ip.SerializeTo(buf, opts)

                    packetDataToGo := buf.Bytes()

                    // send the packet
                    handle.WritePacketData(packetDataToGo)
                }
            }
        }
    }
}
Jan Zerebecki
  • 825
  • 7
  • 18
Jonathan Eustace
  • 2,469
  • 12
  • 31
  • 54
  • 1
    Make sure you didn't get network/host ordering mixed up on the edit, and then you need to recompute the checksums that are now invalidated. – Rob Mar 11 '15 at 21:21
  • 3
    **Never** use the two value version of [type assertion](https://golang.org/ref/spec#Type_assertions) if you aren't going to check the second value. The single value version **requires** the type matches and will panic on failure (with a reasonable message) whereas the two value version will always succeed (returning `nil, false` where the type is wrong). – Dave C Mar 12 '15 at 02:10

0 Answers0