func InjectPacket(pp *PacketParams, g *graph.Graph) error {
	srcdata := pp.SrcNode.Metadata()
	dstdata := pp.DstNode.Metadata()

	if _, ok := srcdata["IPV4"]; !ok {
		return errors.New("Source Node doesn't have an IP")
	}

	srcIP := getIP(srcdata["IPV4"].(string))
	if srcIP == nil {
		return errors.New("Source Node doesn't have proper IP")
	}

	if _, ok := dstdata["IPV4"]; !ok {
		return errors.New("Destination Node doesn't have an IP")
	}

	dstIP := getIP(dstdata["IPV4"].(string))
	if dstIP == nil {
		return errors.New("Destination Node doesn't have proper IP")
	}

	srcMAC, err := net.ParseMAC(srcdata["MAC"].(string))
	if err != nil || srcMAC == nil {
		return errors.New("Source Node doesn't have proper MAC")
	}

	dstMAC, err := net.ParseMAC(dstdata["MAC"].(string))
	if err != nil || dstMAC == nil {
		return errors.New("Destination Node doesn't have proper MAC")
	}

	//create packet
	buffer := gopacket.NewSerializeBuffer()
	ipLayer := &layers.IPv4{Version: 4, SrcIP: srcIP, DstIP: dstIP}
	ethLayer := &layers.Ethernet{EthernetType: layers.EthernetTypeIPv4, SrcMAC: srcMAC, DstMAC: dstMAC}

	switch pp.Type {
	case "icmp":
		ipLayer.Protocol = layers.IPProtocolICMPv4
		gopacket.SerializeLayers(buffer, options,
			ethLayer,
			ipLayer,
			&layers.ICMPv4{
				TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0),
			},
			gopacket.Payload([]byte(pp.Payload)),
		)
	default:
		return fmt.Errorf("Unsupported traffic type '%s'", pp.Type)
	}

	g.RLock()

	srcNode := g.GetNode(pp.SrcNode.ID)
	if srcNode == nil {
		g.RUnlock()
		return errors.New("Unable to find source node")
	}

	nscontext, err := topology.NewNetNSContextByNode(g, srcNode)
	defer nscontext.Close()

	g.RUnlock()

	if err != nil {
		return err
	}

	handle, err := pcap.OpenLive(srcdata["Name"].(string), 1024, false, 2000)
	if err != nil {
		return fmt.Errorf("Unable to open the source node: %s", err.Error())
	}
	defer handle.Close()

	packet := buffer.Bytes()
	for i := 0; i < pp.Count; i++ {
		if err := handle.WritePacketData(packet); err != nil {
			return fmt.Errorf("Write error: %s", err.Error())
		}
	}

	return nil
}
Beispiel #2
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)
}