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 }
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) }