Example #1
0
func (self actionPopMpls) Process(data *Frame) (*outputToPort, *outputToGroup, error) {
	var buf []gopacket.Layer
	found := false
	reparse := false
	for i, layer := range data.Layers() {
		if found == false {
			if layer.LayerType() == layers.LayerTypeMPLS {
				if i < 1 {
					return nil, nil, errors.New("pop mpls failed due to packet format")
				}
				base := data.layers[i-1]
				if base.LayerType() == layers.LayerTypeEthernet {
					base.(*layers.Ethernet).EthernetType = layers.EthernetType(self.Ethertype)
				} else if base.LayerType() == layers.LayerTypeDot1Q {
					base.(*layers.Dot1Q).Type = layers.EthernetType(self.Ethertype)
				} else {
					return nil, nil, errors.New("unsupported")
				}

				if t, ok := layer.(*layers.MPLS); ok {
					if t.StackBottom {
						reparse = true
					}
				}

				found = true
				continue
			}
		}
		buf = append(buf, layer)
	}
	if found {
		data.layers = buf
		if reparse {
			if serialized, err := data.Serialized(); err != nil {
				return nil, nil, err
			} else {
				data.serialized = serialized
				data.layers = buf[:0]
			}
		}
	} else {
		return nil, nil, errors.New("pop mpls failed")
	}
	return nil, nil, nil
}
Example #2
0
func decodePBB(data []byte, p gopacket.PacketBuilder) error {
	if data[0]&0x3 != 0 {
		return errors.New("I-TAG TCI Res2 must be zero")
	}
	pbb := &PBB{
		Priority:           data[0] >> 5,
		DropEligible:       data[0]&0x10 != 0,
		UseCustomerAddress: data[0]&0x08 != 0,
		ServiceIdentifier:  binary.BigEndian.Uint32(append(make([]byte, 1), data[1:4]...)),
		DstMAC:             net.HardwareAddr(data[4:10]),
		SrcMAC:             net.HardwareAddr(data[10:16]),
		Type:               layers.EthernetType(binary.BigEndian.Uint16(data[16:18])),
		BaseLayer:          layers.BaseLayer{Contents: data[:18], Payload: data[18:]},
	}
	p.AddLayer(pbb)
	return p.NextDecoder(pbb.Type)
}
Example #3
0
func (m *memh2pcap) Open(w io.Writer) (err error) {
	defer errs.PassE(&err)
	m.pw = pcapgo.NewWriter(w)
	errs.CheckE(m.pw.WriteFileHeader(65536, layers.LinkTypeEthernet))

	eth := &layers.Ethernet{
		SrcMAC:       net.HardwareAddr([]byte{0, 22, 33, 44, 55, 66}),
		DstMAC:       net.HardwareAddr([]byte{11, 22, 33, 44, 55, 77}),
		EthernetType: layers.EthernetType(0x800),
	}
	ip := &layers.IPv4{
		Version:  4,
		SrcIP:    net.IP{1, 2, 3, 4},
		DstIP:    net.IP{233, 54, 12, 1},
		TTL:      1,
		Protocol: layers.IPProtocolUDP,
	}
	udp := &layers.UDP{
		SrcPort: 1,
		DstPort: 18001,
	}
	errs.CheckE(udp.SetNetworkLayerForChecksum(ip))
	mold := &nasdaq.MoldUDP64{
		Session:        "TestSess00",
		SequenceNumber: 0,
		MessageCount:   1,
	}
	moldMb := &nasdaq.MoldUDP64MessageBlockChained{}

	m.mold = mold
	m.layers = append([]gopacket.SerializableLayer{}, moldMb, mold, udp, ip, eth)

	m.sb = gopacket.NewSerializeBuffer()
	m.so = gopacket.SerializeOptions{
		FixLengths:       true,
		ComputeChecksums: true,
	}
	return
}
Example #4
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)
}
Example #5
0
func (self actionPush) Process(data *Frame) (*outputToPort, *outputToGroup, error) {
	var buf []gopacket.Layer
	found := false
	switch self.Type {
	case ofp4.OFPAT_PUSH_VLAN:
		for i, layer := range data.Layers() {
			buf = append(buf, layer)

			if found == false {
				switch layer.LayerType() {
				case layers.LayerTypeEthernet:
					eth := layer.(*layers.Ethernet)
					ethertype := eth.EthernetType
					eth.EthernetType = layers.EthernetType(self.Ethertype)

					dot1q := &layers.Dot1Q{Type: ethertype}
					if d, ok := data.layers[i+1].(*layers.Dot1Q); ok {
						dot1q.Priority = d.Priority
						dot1q.DropEligible = d.DropEligible
						dot1q.VLANIdentifier = d.VLANIdentifier
					}
					buf = append(buf, dot1q)
					found = true
				}
			}
		}
	case ofp4.OFPAT_PUSH_MPLS:
		for i, layer := range data.Layers() {
			if found == false {
				var ttl uint8
				var base gopacket.Layer
				var mpls *layers.MPLS

				switch t := layer.(type) {
				case *layers.MPLS:
					base = data.layers[i-1]
					ttl = t.TTL
					mpls = t
				case *layers.IPv4:
					base = data.layers[i-1]
					ttl = t.TTL
				case *layers.IPv6:
					base = data.layers[i-1]
					ttl = t.HopLimit
				case *layers.ARP:
					base = data.layers[i-1]
				}
				if base != nil {
					if base.LayerType() == layers.LayerTypeEthernet {
						base.(*layers.Ethernet).EthernetType = layers.EthernetType(self.Ethertype)
					} else if base.LayerType() == layers.LayerTypeDot1Q {
						base.(*layers.Dot1Q).Type = layers.EthernetType(self.Ethertype)
					} else {
						return nil, nil, errors.New("unsupported")
					}
					if mpls != nil {
						buf = append(buf, &layers.MPLS{
							Label:        mpls.Label,
							TrafficClass: mpls.TrafficClass,
							StackBottom:  false,
							TTL:          ttl,
						})
					} else {
						buf = append(buf, &layers.MPLS{
							StackBottom: true,
							TTL:         ttl,
						})
					}
					found = true
				}
			}
			buf = append(buf, layer)
		}
	case ofp4.OFPAT_PUSH_PBB:
		for _, layer := range data.Layers() {
			buf = append(buf, layer)
			if found == false {
				switch layer.LayerType() {
				case layers.LayerTypeEthernet:
					eth := layer.(*layers.Ethernet)
					ethertype := eth.EthernetType
					eth.EthernetType = layers.EthernetType(self.Ethertype)
					buf = append(buf, &layers2.PBB{
						DstMAC: eth.DstMAC,
						SrcMAC: eth.SrcMAC,
						Type:   ethertype,
					})
					found = true
				}
			}
		}
	default:
		return nil, nil, ofp4.MakeErrorMsg(
			ofp4.OFPET_BAD_ACTION,
			ofp4.OFPBAC_BAD_TYPE,
		)
	}
	if found {
		data.layers = buf
	} else {
		return nil, nil, errors.New("push vlan failed")
	}
	return nil, nil, nil
}