proper way to modify or replace an application-layer payload
- Dominant language
- Go
- Stars
- 6.8k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
Huge fan of gopacket, thanks for all the great work! I'm working on a project that leverages it heavily. We deal with pcaps and have a need to obscure some packet payloads read from a file before writing the modified packet out to a new file. The goal is to leave the rest of the packet untouched, but replace payload bytes with a useless character ("*" for example).
I've used the approach described [in Issue 765](https://github.com/google/gopacket/issues/765) with some success. It seems to work fine for TCP, even with other app layer protocols supported by gopacket like HTTP. However when the following block encounters a UDP DNS packet it panics with `panic: interface conversion: gopacket.ApplicationLayer is *layers.DNS, not *gopacket.Payload`.
```
if appLayer := packet.ApplicationLayer(); appLayer != nil {
payloadLen := len(appLayer.LayerContents())
var newPayload = make([]byte, payloadLen)
for i := range newPayload {
newPayload[i] = blank
}
*packet.ApplicationLayer().(*gopacket.Payload) = newPayload
}
```
I've also tried doing this at the Transport layer by replacing the layer's payload directly. But this feels wrong knowing that the payload has already been decoded as DNS.
```
payloadLen := len(packet.TransportLayer().LayerPayload())
var newPayload = make([]byte, payloadLen)
for i := range newPayload {
newPayload[i] = blank
}
if udp := packet.TransportLayer().(*layers.UDP); udp != nil {
udp.Payload = newPayload
} else if tcp := packet.TransportLayer().(*layers.TCP); tcp != nil {
udp.Payload = newPayload
}
```
Not surprisingly gopacket.SerializePacket() throws an error `layer DecodeFailure is not serializable` when I then try to serialize the packet with the modified transport payload. I'm clearly missing a step or going about this wrong. Perhaps there is a way to reinitialize the modified packet telling gopacket not to treat it as DNS anymore?
I've also considered assembling a new packet from the layers of the original, but swapping the payload for a new `gopacket.Payload`. This could work but means I'm creating another copy of the packet. I'd rather modify the original in place if possible. But what is the correct way?
Contributor guide
Assessment
This issue has not been assessed yet.