Пример #1
0
// 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)
}