// Given an EvePacket, convert the payload to a PCAP faking out the // headers as best we can. // // A buffer containing the 1 packet pcap file will be returned. func EvePayloadToPcap(event *EveEvent) ([]byte, error) { buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } payloadLayer := gopacket.Payload(event.Payload.Bytes()) payloadLayer.SerializeTo(buffer, options) srcIp := net.ParseIP(event.SrcIP) if srcIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.SrcIP) } dstIp := net.ParseIP(event.DstIP) if dstIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.DstIP) } proto, err := ProtoNumber(event.Proto) if err != nil { return nil, err } switch proto { case layers.IPProtocolTCP: // Could probably fake up a better TCP layer here. tcpLayer := layers.TCP{ SrcPort: layers.TCPPort(event.SrcPort), DstPort: layers.TCPPort(event.DstPort), } tcpLayer.SerializeTo(buffer, options) break case layers.IPProtocolUDP: udpLayer := layers.UDP{ SrcPort: layers.UDPPort(event.SrcPort), DstPort: layers.UDPPort(event.DstPort), } udpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv4: icmpLayer := layers.ICMPv4{ TypeCode: layers.CreateICMPv4TypeCode( event.IcmpType, event.IcmpCode), Id: 0, Seq: 0, } icmpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv6: icmp6Layer := layers.ICMPv6{ TypeCode: layers.CreateICMPv6TypeCode( event.IcmpType, event.IcmpCode), } icmp6Layer.SerializeTo(buffer, options) break default: return nil, fmt.Errorf("Unsupported protocol %d.", proto) } isIp6 := dstIp.To4() == nil if !isIp6 { ipLayer := layers.IPv4{ SrcIP: srcIp, DstIP: dstIp, Version: 4, Protocol: proto, TTL: 64, } ipLayer.SerializeTo(buffer, options) } else { ip6Layer := layers.IPv6{ Version: 6, SrcIP: srcIp, DstIP: dstIp, } ip6Layer.SerializeTo(buffer, options) } return pcap.CreatePcap(event.Timestamp.Time, buffer.Bytes(), layers.LinkTypeRaw) }