Example #1
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
}
Example #2
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)
}