Пример #1
0
/* protos must contain a UDP or TCP layer on top of IPv4 */
func forgeTestPacket(t *testing.T, seed int64, protos ...ProtocolType) *gopacket.Packet {
	rnd := rand.New(rand.NewSource(seed))

	rawBytes := []byte{10, 20, 30}
	var protoStack []gopacket.SerializableLayer

	for i, proto := range protos {
		switch proto {
		case ETH:
			ethernetLayer := &layers.Ethernet{
				SrcMAC:       net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))},
				DstMAC:       net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD},
				EthernetType: layers.EthernetTypeIPv4,
			}
			protoStack = append(protoStack, ethernetLayer)
		case IPv4:
			ipv4Layer := &layers.IPv4{
				SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))},
				DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8},
			}
			switch protos[i+1] {
			case TCP:
				ipv4Layer.Protocol = layers.IPProtocolTCP
			case UDP:
				ipv4Layer.Protocol = layers.IPProtocolUDP
			}
			protoStack = append(protoStack, ipv4Layer)
		case TCP:
			tcpLayer := &layers.TCP{
				SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
				DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))),
			}
			protoStack = append(protoStack, tcpLayer)
		case UDP:
			udpLayer := &layers.UDP{
				SrcPort: layers.UDPPort(byte(rnd.Intn(0x10000))),
				DstPort: layers.UDPPort(byte(rnd.Intn(0x10000))),
			}
			protoStack = append(protoStack, udpLayer)
		default:
			t.Log("forgeTestPacket : Unsupported protocol ", proto)
		}
	}
	protoStack = append(protoStack, gopacket.Payload(rawBytes))

	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{FixLengths: true}
	err := gopacket.SerializeLayers(buffer, options, protoStack...)

	if err != nil {
		t.Fail()
	}

	gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
	return &gpacket
}
Пример #2
0
func (fl *FlowLayer) Hash() []byte {
	if fl == nil {
		return []byte{}
	}
	if fl.Protocol == FlowProtocol_ETHERNET {
		amac, err := net.ParseMAC(fl.A)
		if err != nil {
			panic(err)
		}
		bmac, err := net.ParseMAC(fl.B)
		if err != nil {
			panic(err)
		}
		return HashFromValues(amac, bmac)
	}
	if fl.Protocol == FlowProtocol_IPV4 || fl.Protocol == FlowProtocol_IPV6 {
		aip := net.ParseIP(fl.A)
		bip := net.ParseIP(fl.B)
		return HashFromValues(aip, bip)
	}
	if fl.Protocol == FlowProtocol_TCPPORT {
		aTCPPort, err := strconv.ParseUint(fl.A, 10, 16)
		if err != nil {
			panic(err)
		}
		bTCPPort, err := strconv.ParseUint(fl.B, 10, 16)
		if err != nil {
			panic(err)
		}
		return HashFromValues(layers.TCPPort(aTCPPort), layers.TCPPort(bTCPPort))
	}
	if fl.Protocol == FlowProtocol_UDPPORT {
		aUDPPort, err := strconv.ParseUint(fl.A, 10, 16)
		if err != nil {
			panic(err)
		}
		bUDPPort, err := strconv.ParseUint(fl.B, 10, 16)
		if err != nil {
			panic(err)
		}
		return HashFromValues(layers.UDPPort(aUDPPort), layers.UDPPort(bUDPPort))
	}
	if fl.Protocol == FlowProtocol_SCTPPORT {
		aSCTPPort, err := strconv.ParseUint(fl.A, 10, 16)
		if err != nil {
			panic(err)
		}
		bSCTPPort, err := strconv.ParseUint(fl.B, 10, 16)
		if err != nil {
			panic(err)
		}
		return HashFromValues(layers.SCTPPort(aSCTPPort), layers.SCTPPort(bSCTPPort))
	}
	return nil
}
Пример #3
0
func (p *reusingProcessor) ProcessAll() (err error) {
	defer errs.PassE(&err)
	pd := NewUdpDstPortPayloadDetector()
	for port := 30100; port < 30200; port++ {
		pd.addPortMap(layers.UDPPort(port), bats.LayerTypeBSU)
	}
	for port := 51000; port < 51100; port++ {
		pd.addPortMap(layers.UDPPort(port), miax.LayerTypeMachTop)
	}
	for port := 18000; port < 18010; port++ {
		pd.addPortMap(layers.UDPPort(port), nasdaq.LayerTypeMoldUDP64)
	}
	pmlf := &payloadMuxLayerFactory{}
	pmlf.AddDetector(pd)

	parser := packet.NewReusingLayerParser(layers.LayerTypeEthernet)
	parser.AddDecodingLayerFactory(EthernetLayerFactory)
	parser.AddDecodingLayerFactory(Dot1QLayerFactory)
	parser.AddDecodingLayerFactory(IPv4LayerFactory)
	parser.AddDecodingLayerFactory(UDPLayerFactory)
	parser.AddDecodingLayerFactory(TcpIgnoreLayerFactory)
	parser.AddDecodingLayerFactory(pmlf)
	parser.AddDecodingLayerFactory(miax.MachTopLayerFactory)
	parser.AddDecodingLayerFactory(miax.MachLayerFactory)
	parser.AddDecodingLayerFactory(miax.TomLayerFactory)
	parser.AddDecodingLayerFactory(bats.BSULayerFactory)
	parser.AddDecodingLayerFactory(bats.PitchLayerFactory)
	parser.AddDecodingLayerFactory(nasdaq.MoldUDP64LayerFactory)
	parser.AddDecodingLayerFactory(nasdaq.MoldUDP64MessageBlockLayerFactory)
	parser.AddDecodingLayerFactory(nasdaq.IttoLayerFactory)

	packetNumLimit := -1
	if p.packetNumLimit > 0 {
		packetNumLimit = p.packetNumLimit
	}
	var decoded []gopacket.DecodingLayer
	pmlf.SetDecodedLayers(&decoded)
	for packetNum := 0; packetNum != packetNumLimit; packetNum++ {
		//log.Printf("packetNum: %d\n", packetNum)
		data, ci, err := p.obtainer.ZeroCopyReadPacketData()
		if err == io.EOF {
			break
		}
		errs.CheckE(err)
		errs.CheckE(parser.DecodeLayers(data, &decoded))
		errs.CheckE(p.ProcessPacket(data, ci, decoded))
	}
	return
}
Пример #4
0
func (sender *RawUDPSender) Send(msg []byte) error {
	payload := gopacket.Payload(msg)
	sender.udpHeader.DstPort = layers.UDPPort(sender.conn.RemoteUDPAddr().Port)

	err := gopacket.SerializeLayers(sender.ipBuf, sender.opts, sender.udpHeader, &payload)
	if err != nil {
		return err
	}
	packet := sender.ipBuf.Bytes()
	_, err = sender.socket.Write(packet)
	if err == nil || PosixError(err) != syscall.EMSGSIZE {
		return err
	}
	f, err := sender.socket.File()
	if err != nil {
		return err
	}
	defer f.Close()
	fd := int(f.Fd())
	log.Println("EMSGSIZE on send, expecting PMTU update (IP packet was",
		len(packet), "bytes, payload was", len(msg), "bytes)")
	pmtu, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MTU)
	if err != nil {
		return err
	}
	return MsgTooBigError{PMTU: pmtu}
}
Пример #5
0
/*
   FUNCTION: craftPacket(data []byte, ip string, port uint16, payload []byte) []byte
   RETURNS: []byte, byte array containing packet data created
   ARGUMENTS:
             []byte data - data to be placed in the source port
             string ip   - address to place in the dst ip of the ip layer
             uint16 port - destination port of udp header
             []byte payload - udp payload to be passed in

   ABOUT:
   Crafts a packet with a IP, ethernet and UDP header. Covertly inserts data into
   the source port and appends the specified payload.
*/
func craftPacket(data []byte, ip string, port uint16, payload []byte) []byte {

	ethernetLayer := &layers.Ethernet{
		SrcMAC:       localmac,
		DstMAC:       destmac,
		EthernetType: layers.EthernetTypeIPv4,
	}

	ipLayer := &layers.IPv4{
		Version:    4,
		IHL:        5,
		TOS:        0,
		Length:     20,
		Id:         2,
		Flags:      layers.IPv4DontFragment,
		FragOffset: 0,
		TTL:        255,
		Protocol:   layers.IPProtocolUDP,
		Checksum:   0,
		SrcIP:      localip,
		DstIP:      net.ParseIP(ip),
	}

	val := binary.BigEndian.Uint16(data)
	udpLayer := &layers.UDP{
		SrcPort: layers.UDPPort(MAX_PORT - val),
		DstPort: layers.UDPPort(port),
		Length:  16,
	}

	err := udpLayer.SetNetworkLayerForChecksum(ipLayer)
	checkError(err)

	buf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	err = gopacket.SerializeLayers(buf, opts, ethernetLayer, ipLayer, udpLayer, gopacket.Payload(payload))
	checkError(err)

	return buf.Bytes()
}
Пример #6
0
func (p *GoPacketProbesHandler) RegisterProbe(n *graph.Node, capture *api.Capture, ft *flow.Table) error {
	name, ok := n.Metadata()["Name"]
	if !ok || name == "" {
		return fmt.Errorf("No name for node %v", n)
	}

	encapType, ok := n.Metadata()["EncapType"]
	if !ok || encapType == "" {
		return fmt.Errorf("No EncapType for node %v", n)
	}

	tid, ok := n.Metadata()["TID"]
	if !ok {
		return fmt.Errorf("No TID for node %v", n)
	}

	id := string(n.ID)
	ifName := name.(string)

	if _, ok = p.probes[id]; ok {
		return fmt.Errorf("Already registered %s", ifName)
	}

	port, ok := n.Metadata()["MPLSUDPPort"].(int)
	if ok {
		// All gopacket instance of this agent will classify UDP packets coming
		// from UDP port MPLSUDPPort as MPLS whatever the source interface
		layers.RegisterUDPPortLayerType(layers.UDPPort(port), layers.LayerTypeMPLS)
		logging.GetLogger().Infof("MPLSoUDP port: %v", port)
	}

	probe := &GoPacketProbe{
		NodeTID:   tid.(string),
		state:     common.StoppedState,
		flowTable: ft,
	}

	p.probesLock.Lock()
	p.probes[id] = probe
	p.probesLock.Unlock()
	p.wg.Add(1)

	go func() {
		defer p.wg.Done()

		probe.run(p.graph, n, capture)
	}()

	return nil
}
Пример #7
0
func newUDPSenderDF(localIP net.IP, localPort int) *udpSenderDF {
	return &udpSenderDF{
		ipBuf: gopacket.NewSerializeBuffer(),
		opts: gopacket.SerializeOptions{
			FixLengths: true,
			// UDP header is calculated with a phantom IP
			// header. Yes, it's totally nuts. Thankfully,
			// for UDP over IPv4, the checksum is
			// optional. It's not optional for IPv6, but
			// we'll ignore that for now. TODO
			ComputeChecksums: false,
		},
		udpHeader: &layers.UDP{SrcPort: layers.UDPPort(localPort)},
		localIP:   localIP,
	}
}
Пример #8
0
func ianaPort(layerType gopacket.LayerType, port uint16) string {
	if layerType == layers.LayerTypeTCP {
		proto, in := layers.TCPPortNames[layers.TCPPort(port)]
		if in {
			return fmt.Sprintf("%s (TCP)", proto)
		} else {
			return "N/A (TCP)"
		}
	} else {
		proto, in := layers.UDPPortNames[layers.UDPPort(port)]
		if in {
			return fmt.Sprintf("%s (UDP)", proto)
		} else {
			return "N/A (UDP)"
		}
	}
}
Пример #9
0
func TestFlowEncaspulationMplsUdp(t *testing.T) {
	layers.RegisterUDPPortLayerType(layers.UDPPort(444), layers.LayerTypeMPLS)
	table := NewTable(nil, nil)
	packet := forgeTestPacket(t, 64, false, ETH, IPv4, UDP_MPLS, MPLS, IPv4, TCP)
	flowPackets := FlowPacketsFromGoPacket(packet, 0)
	table.FlowPacketsToFlow(flowPackets)

	flows := table.GetFlows(nil).GetFlows()
	if len(flows) != 2 {
		t.Error("An MPLSoUDP packet must generate 2 flows")
	}

	flows = sortFlowByRelationship(flows)

	if flows[0].LayersPath != "Ethernet/IPv4/UDP/MPLS" || flows[1].LayersPath != "IPv4/TCP/Payload" {
		t.Errorf("Flows LayersPath must be Ethernet/IPv4/UDP/MPLS | IPv4/TCP/Payload")
	}
}
Пример #10
0
func (sender *udpSenderDF) send(msg []byte, raddr *net.UDPAddr) error {
	// Ensure we have a socket sending to the right IP address
	if sender.socket == nil || !bytes.Equal(sender.remoteIP, raddr.IP) {
		sender.remoteIP = raddr.IP
		if err := sender.dial(); err != nil {
			return err
		}
	}

	sender.udpHeader.DstPort = layers.UDPPort(raddr.Port)
	payload := gopacket.Payload(msg)
	err := gopacket.SerializeLayers(sender.ipBuf, sender.opts,
		sender.udpHeader, &payload)
	if err != nil {
		return err
	}

	packet := sender.ipBuf.Bytes()
	_, err = sender.socket.Write(packet)
	if err == nil || PosixError(err) != syscall.EMSGSIZE {
		return err
	}

	f, err := sender.socket.File()
	if err != nil {
		return err
	}
	defer f.Close()

	log.Print("EMSGSIZE on send, expecting PMTU update (IP packet was ",
		len(packet), " bytes, payload was ", len(msg), " bytes)")
	pmtu, err := syscall.GetsockoptInt(int(f.Fd()), syscall.IPPROTO_IP,
		syscall.IP_MTU)
	if err != nil {
		return err
	}

	return msgTooBigError{underlayPMTU: pmtu}
}
Пример #11
0
func (c *Capture) StartFromPCAP(file string, port int) (err error) {

	handle, err := pcap.OpenOffline(file)
	if err != nil {
		log.Fatal("PCAP OpenOffline error:", err)
	}

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

	for packet := range packetSource.Packets() {
		udpLayer := packet.Layer(layers.LayerTypeUDP)
		udp, ok := udpLayer.(*layers.UDP)
		if ok && udp != nil {
			if udp.DstPort != layers.UDPPort(port) {
				m := NewRawMessage(udp.Payload)
				c.processDefault(m)
			}
		}

	}
	return
}
Пример #12
0
func NewRawUDPSender(conn *LocalConnection) (*RawUDPSender, error) {
	ipSocket, err := dialIP(conn)
	if err != nil {
		return nil, err
	}
	udpHeader := &layers.UDP{SrcPort: layers.UDPPort(conn.Router.Port)}
	ipBuf := gopacket.NewSerializeBuffer()
	opts := gopacket.SerializeOptions{
		FixLengths: true,
		// UDP header is calculated with a phantom IP
		// header. Yes, it's totally nuts. Thankfully, for UDP
		// over IPv4, the checksum is optional. It's not
		// optional for IPv6, but we'll ignore that for
		// now. TODO
		ComputeChecksums: false}

	return &RawUDPSender{
		ipBuf:     ipBuf,
		opts:      opts,
		udpHeader: udpHeader,
		socket:    ipSocket,
		conn:      conn}, nil
}
Пример #13
0
func (self oxmBasic) SetField(data *Frame, key OxmKey, payload OxmPayload) error {
	m := payload.(OxmValueMask)
	switch uint32(key.(OxmKeyBasic)) {
	default:
		return fmt.Errorf("unknown oxm field")
	case oxm.OXM_OF_IN_PORT:
		data.inPort = binary.BigEndian.Uint32(m.Value)
		return nil
	case oxm.OXM_OF_IN_PHY_PORT:
		data.inPhyPort = binary.BigEndian.Uint32(m.Value)
		return nil
	case oxm.OXM_OF_METADATA:
		data.metadata = binary.BigEndian.Uint64(m.Value)
		return nil
	case oxm.OXM_OF_ETH_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.Ethernet); ok {
				t.DstMAC = net.HardwareAddr(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_ETH_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.Ethernet); ok {
				t.SrcMAC = net.HardwareAddr(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_ETH_TYPE:
		var lastLayer gopacket.Layer
		for _, layer := range data.Layers() {
			switch t := layer.(type) {
			case *layers.Ethernet:
				lastLayer = t
			case *layers.Dot1Q:
				lastLayer = t
			}
		}
		if t, ok := lastLayer.(*layers.Ethernet); ok {
			t.EthernetType = layers.EthernetType(binary.BigEndian.Uint16(m.Value))
			return nil
		}
		if t, ok := lastLayer.(*layers.Dot1Q); ok {
			t.Type = layers.EthernetType(binary.BigEndian.Uint16(m.Value))
			return nil
		}
	case oxm.OXM_OF_VLAN_VID:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.Dot1Q); ok {
				t.VLANIdentifier = binary.BigEndian.Uint16(m.Value) & 0x0fff
				return nil
			}
		}
	case oxm.OXM_OF_VLAN_PCP:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.Dot1Q); ok {
				t.Priority = m.Value[0]
				return nil
			}
		}
	case oxm.OXM_OF_IP_DSCP:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv4); ok {
				t.TOS = t.TOS&0x03 | m.Value[0]<<2
				return nil
			}
			if t, ok := layer.(*layers.IPv6); ok {
				t.TrafficClass = t.TrafficClass&0x03 | m.Value[0]<<2
				return nil
			}
		}
	case oxm.OXM_OF_IP_ECN:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv4); ok {
				t.TOS = t.TOS&0xFC | m.Value[0]&0x03
				return nil
			}
			if t, ok := layer.(*layers.IPv6); ok {
				t.TrafficClass = t.TrafficClass&0xFC | m.Value[0]&0x03
				return nil
			}
		}
	case oxm.OXM_OF_IP_PROTO:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv4); ok {
				t.Protocol = layers.IPProtocol(m.Value[0])
				return nil
			}
			if t, ok := layer.(*layers.IPv6); ok {
				t.NextHeader = layers.IPProtocol(m.Value[0])
				return nil
			}
		}
	case oxm.OXM_OF_IPV4_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv4); ok {
				t.SrcIP = net.IP(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_IPV4_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv4); ok {
				t.DstIP = net.IP(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_TCP_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.TCP); ok {
				t.SrcPort = layers.TCPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_TCP_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.TCP); ok {
				t.DstPort = layers.TCPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_UDP_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.UDP); ok {
				t.SrcPort = layers.UDPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_UDP_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.UDP); ok {
				t.DstPort = layers.UDPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_SCTP_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.SCTP); ok {
				t.SrcPort = layers.SCTPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_SCTP_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.SCTP); ok {
				t.DstPort = layers.SCTPPort(binary.BigEndian.Uint16(m.Value))
				return nil
			}
		}
	case oxm.OXM_OF_ICMPV4_TYPE:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv4); ok {
				t.TypeCode = layers.ICMPv4TypeCode(uint16(t.TypeCode)&0x00FF | uint16(m.Value[0])<<8)
				return nil
			}
		}
	case oxm.OXM_OF_ICMPV4_CODE:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv4); ok {
				t.TypeCode = layers.ICMPv4TypeCode(uint16(t.TypeCode)&0xFF00 | uint16(m.Value[0]))
				return nil
			}
		}
	case oxm.OXM_OF_ARP_OP:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ARP); ok {
				t.Operation = binary.BigEndian.Uint16(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_ARP_SPA:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ARP); ok {
				t.SourceProtAddress = m.Value
				return nil
			}
		}
	case oxm.OXM_OF_ARP_TPA:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ARP); ok {
				t.DstProtAddress = m.Value
				return nil
			}
		}
	case oxm.OXM_OF_ARP_SHA:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ARP); ok {
				t.SourceHwAddress = m.Value
				return nil
			}
		}
	case oxm.OXM_OF_ARP_THA:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ARP); ok {
				t.DstHwAddress = m.Value
				return nil
			}
		}
	case oxm.OXM_OF_IPV6_SRC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv6); ok {
				t.SrcIP = net.IP(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_IPV6_DST:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv6); ok {
				t.DstIP = net.IP(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_IPV6_FLABEL:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.IPv6); ok {
				t.FlowLabel = binary.BigEndian.Uint32(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_ICMPV6_TYPE:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv6); ok {
				t.TypeCode = layers.ICMPv6TypeCode(uint16(t.TypeCode)&0x00FF | uint16(m.Value[0])<<8)
				return nil
			}
		}
	case oxm.OXM_OF_ICMPV6_CODE:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv6); ok {
				t.TypeCode = layers.ICMPv6TypeCode(uint16(t.TypeCode)&0xFF00 | uint16(m.Value[0]))
				return nil
			}
		}
	case oxm.OXM_OF_IPV6_ND_TARGET:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv6); ok {
				typ := uint8(t.TypeCode >> 8)
				if typ == layers.ICMPv6TypeNeighborSolicitation || typ == layers.ICMPv6TypeNeighborAdvertisement {
					copy(t.Payload[:16], m.Value)
					return nil
				}
			}
		}
	case oxm.OXM_OF_IPV6_ND_SLL:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv6); ok {
				typ := uint8(t.TypeCode >> 8)
				if typ == layers.ICMPv6TypeNeighborSolicitation {
					for cur := 16; cur < len(t.Payload); {
						length := int(t.Payload[cur+1]) * 8
						if t.Payload[cur] == 1 { // source link-layer address (RFC 2461 4.6)
							copy(t.Payload[cur+2:], m.Value)
							return nil
						}
						cur += length
					}
					buf := make([]byte, 8)
					buf[0] = 2
					buf[1] = 1
					copy(buf[2:], m.Value)
					t.Payload = append(t.Payload, buf...)
					return nil
				}
			}
		}
	case oxm.OXM_OF_IPV6_ND_TLL:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.ICMPv6); ok {
				typ := uint8(t.TypeCode >> 8)
				if typ == layers.ICMPv6TypeNeighborAdvertisement {
					for cur := 16; cur < len(t.Payload); {
						length := int(t.Payload[cur+1]) * 8
						if t.Payload[cur] == 2 { // target link-layer address (RFC 2461 4.6)
							copy(t.Payload[cur+2:], m.Value)
							return nil
						}
						cur += length
					}
					buf := make([]byte, 8)
					buf[0] = 2
					buf[1] = 1
					copy(buf[2:], m.Value)
					t.Payload = append(t.Payload, buf...)
					return nil
				}
			}
		}
	case oxm.OXM_OF_MPLS_LABEL:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.MPLS); ok {
				t.Label = binary.BigEndian.Uint32(m.Value)
				return nil
			}
		}
	case oxm.OXM_OF_MPLS_TC:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.MPLS); ok {
				t.TrafficClass = m.Value[0]
				return nil
			}
		}
	case oxm.OXM_OF_MPLS_BOS:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers.MPLS); ok {
				if m.Value[0] == 0 {
					t.StackBottom = false
				} else {
					t.StackBottom = true
				}
				return nil
			}
		}
	case oxm.OXM_OF_PBB_ISID:
		for _, layer := range data.Layers() {
			if t, ok := layer.(*layers2.PBB); ok {
				t.ServiceIdentifier = binary.BigEndian.Uint32(append(make([]byte, 1), m.Value...))
				return nil
			}
		}
	case oxm.OXM_OF_TUNNEL_ID:
		data.tunnelId = binary.BigEndian.Uint64(m.Value)
		return nil
	case oxm.OXM_OF_IPV6_EXTHDR:
		return fmt.Errorf("OXM_OF_IPV6_EXTHDR setter is unsupported")
	}
	return fmt.Errorf("layer not found: %v", m)
}
Пример #14
0
/* protos must contain a UDP or TCP layer on top of IPv4 */
func forgeTestPacket(t *testing.T, seed int64, swap bool, protos ...ProtocolType) *gopacket.Packet {
	rnd := rand.New(rand.NewSource(seed))
	rawBytes := []byte{10, 20, 30}
	var protoStack []gopacket.SerializableLayer

	for i, proto := range protos {
		switch proto {
		case GRE:
			greLayer := &layers.GRE{}
			switch protos[i+1] {
			case IPv4:
				greLayer.Protocol = layers.EthernetTypeIPv4
			case IPv6:
				greLayer.Protocol = layers.EthernetTypeIPv6
			default:
				t.Error(fmt.Sprintf("Protocol %s can not be encapsulated in GRE", protos[i+1]))
			}
			protoStack = append(protoStack, greLayer)
		case ETH:
			ethernetLayer := &layers.Ethernet{
				SrcMAC:       net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))},
				DstMAC:       net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD},
				EthernetType: layers.EthernetTypeIPv4,
			}
			if swap {
				ethernetLayer.SrcMAC, ethernetLayer.DstMAC = ethernetLayer.DstMAC, ethernetLayer.SrcMAC
			}
			protoStack = append(protoStack, ethernetLayer)
		case IPv4:
			ipv4Layer := &layers.IPv4{
				SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))},
				DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8},
			}
			switch protos[i+1] {
			case TCP:
				ipv4Layer.Protocol = layers.IPProtocolTCP
			case UDP:
				ipv4Layer.Protocol = layers.IPProtocolUDP
			case GRE:
				ipv4Layer.Protocol = layers.IPProtocolGRE
			}
			if swap {
				ipv4Layer.SrcIP, ipv4Layer.DstIP = ipv4Layer.DstIP, ipv4Layer.SrcIP
			}
			protoStack = append(protoStack, ipv4Layer)
		case TCP:
			tcpLayer := &layers.TCP{
				SrcPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
				DstPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
			}
			if swap {
				tcpLayer.SrcPort, tcpLayer.DstPort = tcpLayer.DstPort, tcpLayer.SrcPort
			}
			protoStack = append(protoStack, tcpLayer)
		case UDP:
			udpLayer := &layers.UDP{
				SrcPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
				DstPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))),
			}
			if swap {
				udpLayer.SrcPort, udpLayer.DstPort = udpLayer.DstPort, udpLayer.SrcPort
			}
			protoStack = append(protoStack, udpLayer)
		default:
			t.Log("forgeTestPacket : Unsupported protocol ", proto)
		}
	}
	protoStack = append(protoStack, gopacket.Payload(rawBytes))

	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{FixLengths: true}
	err := gopacket.SerializeLayers(buffer, options, protoStack...)

	if err != nil {
		t.Fail()
	}

	firstLayerType := layers.LayerTypeEthernet
	switch protos[0] {
	case IPv4:
		firstLayerType = layers.LayerTypeIPv4
	case IPv6:
		firstLayerType = layers.LayerTypeIPv6
	}
	gpacket := gopacket.NewPacket(buffer.Bytes(), firstLayerType, gopacket.Default)
	return &gpacket
}
Пример #15
0
func (vnet *VNET) handleUDPForward(pkt *Packet, now time.Time) {
	defer pkt.Release()
	// fmt.Printf("UDP: %08x %s\n", pkt.Flags, pkt.String())

	var err error

	if bytes.Equal(pkt.Eth.DstMAC, layers.EthernetBroadcast[:]) {
		// ignore
		return
	}

	if pkt.DstHost == nil {
		// ignore
		return
	}
	if !pkt.DstHost.Up {
		log.Printf("destination is down: %s", pkt.DstHost.Name)
		// ignore
		return
	}

	var (
		srcIP   net.IP
		dstIP   net.IP
		srcPort = uint16(pkt.UDP.SrcPort)
		dstPort = uint16(pkt.UDP.DstPort)
	)

	if pkt.IPv4 != nil {
		srcIP = CloneIP(pkt.IPv4.SrcIP.To16())
		dstIP = CloneIP(pkt.IPv4.DstIP.To16())
	} else if pkt.IPv6 != nil {
		srcIP = CloneIP(pkt.IPv6.SrcIP.To16())
		dstIP = CloneIP(pkt.IPv6.DstIP.To16())
	} else {
		log.Printf("invalid protocol")
		// ignore
		return
	}

	route := vnet.routes.GetTable().Lookup(
		protocols.UDP,
		srcIP, dstIP, srcPort, dstPort)

	if route == nil {
		rule, found := vnet.rules.GetTable().Lookup(protocols.UDP, pkt.DstHost.ID, dstPort)
		if !found {
			log.Printf("no rule")
			// ignore
			return
		}

		var ruleDstIP = rule.DstIP

		if ruleDstIP == nil {
			gateway := vnet.hosts.GetTable().LookupByName("gateway")
			if gateway == nil || !gateway.Up {
				log.Printf("no gateway")
				// ignore
				return
			}

			if dstIP.To4() != nil {
				if len(gateway.IPv4Addrs) > 0 {
					ruleDstIP = gateway.IPv4Addrs[0]
				}
			} else {
				if len(gateway.IPv6Addrs) > 0 {
					ruleDstIP = gateway.IPv6Addrs[0]
				}
			}
		}
		if ruleDstIP == nil {
			log.Printf("no destination ip")
			// ignore
			return
		}

		var r routes.Route
		r.Protocol = protocols.UDP
		r.HostID = pkt.DstHost.ID
		r.SetInboundSource(srcIP, srcPort)
		r.SetInboundDestination(dstIP, dstPort)
		r.SetOutboundDestination(ruleDstIP, rule.DstPort)
		route, err = vnet.routes.AddRoute(&r)
		if err != nil {
			// ignore
			log.Printf("UDP/error: %s", err)
			return
		}
	}

	if route == nil {
		log.Printf("no route")
		// ignore
		return
	}

	var (
		eth layers.Ethernet
		udp layers.UDP
	)

	eth = *pkt.Eth
	eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC

	udp = *pkt.UDP
	udp.SrcPort = layers.UDPPort(route.Outbound.SrcPort)
	udp.DstPort = layers.UDPPort(route.Outbound.DstPort)

	if route.Outbound.DstIP.To4() != nil {
		ip := layers.IPv4{
			SrcIP:    route.Outbound.SrcIP.To4(),
			DstIP:    route.Outbound.DstIP.To4(),
			Version:  4,
			Protocol: layers.IPProtocolUDP,
			TTL:      64,
		}

		udp.SetNetworkLayerForChecksum(&ip)

		err = vnet.writePacket(
			&eth,
			&ip,
			&udp,
			gopacket.Payload(pkt.UDP.Payload))
		if err != nil {
			log.Printf("UDP/error: %s", err)
			return
		}

	} else {
		ip := layers.IPv6{
			SrcIP:      route.Outbound.SrcIP.To16(),
			DstIP:      route.Outbound.DstIP.To16(),
			Version:    4,
			NextHeader: layers.IPProtocolUDP,
		}

		udp.SetNetworkLayerForChecksum(&ip)

		err = vnet.writePacket(
			&eth,
			&ip,
			&udp,
			gopacket.Payload(pkt.UDP.Payload))
		if err != nil {
			log.Printf("UDP/error: %s", err)
			return
		}
	}

	route.RoutedPacket(now, len(pkt.buf))
}
Пример #16
0
func (h *dnsStream) creatPacket(msg_buf []byte, nomalPack chan gopacket.Packet) {
	var sourcePort, DesPort int16
	//read the port from tranport flow
	b_buf := bytes.NewBuffer(h.transport.Src().Raw())
	binary.Read(b_buf, binary.BigEndian, &sourcePort)
	b_buf = bytes.NewBuffer(h.transport.Dst().Raw())
	binary.Read(b_buf, binary.BigEndian, &DesPort)
	//new a UDP layer
	udpLayer := layers.UDP{
		BaseLayer: layers.BaseLayer{
			Contents: []byte{},
			Payload:  msg_buf,
		},
		SrcPort:  layers.UDPPort(sourcePort),
		DstPort:  layers.UDPPort(DesPort),
		Length:   1024,
		Checksum: 30026,
	}
	UDPNewSerializBuffer := gopacket.NewSerializeBuffer() // this buffer could be used as a payload of IP layer
	udpBuffer, _ := UDPNewSerializBuffer.PrependBytes(len(msg_buf))

	copy(udpBuffer, msg_buf)

	ops := gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}

	if h.net.EndpointType() == layers.EndpointIPv4 {
		ip_checksum := layers.IPv4{}
		ip_checksum.Version = 4
		ip_checksum.TTL = 0
		ip_checksum.SrcIP = h.net.Src().Raw()
		ip_checksum.DstIP = h.net.Dst().Raw()
		udpLayer.SetNetworkLayerForChecksum(&ip_checksum)
	} else {
		ip6_checksum := layers.IPv6{}
		ip6_checksum.Version = 6
		ip6_checksum.NextHeader = layers.IPProtocolNoNextHeader
		ip6_checksum.HopLimit = 0
		ip6_checksum.SrcIP = h.net.Src().Raw()
		ip6_checksum.DstIP = h.net.Dst().Raw()
		udpLayer.SetNetworkLayerForChecksum(&ip6_checksum)
	}
	err := udpLayer.SerializeTo(UDPNewSerializBuffer, ops)
	if err != nil {
		fmt.Print("error in create udp Layer")
		return
		//err = nil
		//	need err handle there
	}

	fmt.Println("finished creat udplayer, the length is ", udpLayer.Length)
	if h.net.EndpointType() == layers.EndpointIPv4 { // if it is from ipv4, construct a ipv4 layer
		ip := layers.IPv4{
			BaseLayer: layers.BaseLayer{
				Contents: []byte{},
				Payload:  UDPNewSerializBuffer.Bytes(),
			},
			Version:    4,
			IHL:        0,
			TOS:        0,
			Length:     0,
			Id:         0,
			Flags:      0,
			FragOffset: 0,
			TTL:        0,
			Protocol:   layers.IPProtocolUDP,
			Checksum:   0,
			SrcIP:      h.net.Src().Raw(),
			DstIP:      h.net.Dst().Raw(),
			Options:    []layers.IPv4Option{},
			Padding:    []byte{},
		}
		//serialize it and use the serilize buffer to new packet
		IPserializeBuffer := gopacket.NewSerializeBuffer()

		ipBuffer, _ := IPserializeBuffer.PrependBytes(len(UDPNewSerializBuffer.Bytes()))
		copy(ipBuffer, UDPNewSerializBuffer.Bytes())
		err = ip.SerializeTo(IPserializeBuffer, ops)
		if err != nil {
			fmt.Print("error in create ipv4 Layer")
			return
			//err = nil
			//	need err handle there
		}

		fmt.Println("finished creat ip, the length is ", ip.Length)
		resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv4, gopacket.Default)
		resultPack.Metadata().CaptureLength = len(resultPack.Data())
		resultPack.Metadata().Length = len(resultPack.Data())
		//seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value
		nomalPack <- resultPack
		return

	} else if h.net.EndpointType() == layers.EndpointIPv6 {
		// if it is in IPV6 contruct ipv6 packet
		ip := layers.IPv6{
			BaseLayer: layers.BaseLayer{
				Contents: []byte{},
				Payload:  UDPNewSerializBuffer.Bytes(),
			},
			Version:      6,
			TrafficClass: 0,
			FlowLabel:    0,
			Length:       0,
			NextHeader:   layers.IPProtocolNoNextHeader, //no sure what next header should be used there
			HopLimit:     0,
			SrcIP:        h.net.Src().Raw(),
			DstIP:        h.net.Dst().Raw(),
			HopByHop:     nil,
			// hbh will be pointed to by HopByHop if that layer exists.
		}
		IPserializeBuffer := gopacket.NewSerializeBuffer()
		err := ip.SerializeTo(IPserializeBuffer, ops)
		if err != nil {
			fmt.Printf("error in creat IPV6 Layer")
			return
		}
		fmt.Println("finished creat ip, the length is ", ip.Length)
		resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv6, gopacket.Default)
		resultPack.Metadata().CaptureLength = len(resultPack.Data())
		resultPack.Metadata().Length = len(resultPack.Data())
		//seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value
		nomalPack <- resultPack
		return
	} else {
		return //unknown network just return?
	}
}
Пример #17
0
func (vnet *VNET) handleDHCPOffer(pkt *Packet, offer *dhcp.Message) {
	if offer.YourIPAddress == nil {
		return
	}

	msg := &dhcp.Message{}

	msg.ClientMAC = vnet.system.ControllerMAC()

	msg.Type = dhcp.MessageTypeRequest
	msg.HardwareType = dhcp.MessageHardwareTypeEthernet
	msg.HardwareAddressLength = 6
	msg.Hops = 0
	msg.TransactionID = offer.TransactionID
	msg.Options = map[uint8]*dhcp.Option{

		dhcp.OptionCodeDHCPMessageType: {
			Value: []byte{dhcp.DHCPMessageTypeRequest},
		},

		dhcp.OptionCodeDHCPClientidentifier: {
			Value: append([]byte{1}, msg.ClientMAC[:6]...),
		},

		dhcp.OptionCodeDHCPRequestedIPAddress: {
			Value: offer.YourIPAddress.To4(),
		},

		dhcp.OptionCodeDHCPServerIdentifier: offer.Options[dhcp.OptionCodeDHCPServerIdentifier],

		dhcp.OptionCodeDHCPMaximumMessageSize: {
			Value: []byte{2, 64}, // 576
		},

		dhcp.OptionCodeDHCPParameterRequestList: {
			Value: []byte{
				dhcp.OptionCodeSubnetMask,
				dhcp.OptionCodeRouter,
				dhcp.OptionCodeDomainNameServer,
				dhcp.OptionCodeHostName,
				dhcp.OptionCodeDomainName,
				dhcp.OptionCodeBroadcastAddress,
				dhcp.OptionCodeNetworkTimeProtocolServers,
			},
		},

		dhcp.OptionCodeDHCPVendorclassidentifier: {
			Value: []byte("swtchbrd 1.23.1"),
		},

		dhcp.OptionCodeEnd: {},
	}

	ipv4 := &layers.IPv4{
		SrcIP:    net.IPv4(0, 0, 0, 0),
		DstIP:    net.IPv4(255, 255, 255, 255),
		Version:  4,
		Protocol: layers.IPProtocolUDP,
		TTL:      64,
	}

	udp := &layers.UDP{
		SrcPort: layers.UDPPort(68),
		DstPort: layers.UDPPort(67),
	}

	udp.SetNetworkLayerForChecksum(ipv4)

	err := vnet.writePacket(
		&layers.Ethernet{
			SrcMAC:       msg.ClientMAC,
			DstMAC:       layers.EthernetBroadcast,
			EthernetType: layers.EthernetTypeIPv4,
		},
		ipv4,
		udp,
		gopacket.Payload(writeDHCPMessage(msg)))
	if err != nil {
		log.Printf("DCHP/error: %s", err)
		return
	}

	return
}
Пример #18
0
// String returns the port as "number(name)" if there's a well-known port name,
// or just "number" if there isn't.  Well-known names are stored in
// UDPPortNames.
func (a UDPPort) String() string {
	if name, ok := layers.UDPPortNames[layers.UDPPort(a)]; ok {
		return fmt.Sprintf("%d(%s)", a, name)
	}
	return strconv.Itoa(int(a))
}
Пример #19
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)
}