예제 #1
0
func (fs *FlowStatistics) updateTransportLayerStatistics(packet *gopacket.Packet) error {
	if len(fs.Endpoints) <= int(FlowEndpointLayer_TRANSPORT) {
		return errors.New("Unable to decode the transport layer")
	}
	ep := fs.Endpoints[FlowEndpointLayer_TRANSPORT]

	var transportLayer gopacket.Layer
	var srcPort string
	switch ep.Type {
	case FlowEndpointType_TCPPORT:
		transportLayer = (*packet).Layer(layers.LayerTypeTCP)
		transportPacket, _ := transportLayer.(*layers.TCP)
		srcPort = transportPacket.SrcPort.String()
	case FlowEndpointType_UDPPORT:
		transportLayer = (*packet).Layer(layers.LayerTypeUDP)
		transportPacket, _ := transportLayer.(*layers.UDP)
		srcPort = transportPacket.SrcPort.String()
	case FlowEndpointType_SCTPPORT:
		transportLayer = (*packet).Layer(layers.LayerTypeSCTP)
		transportPacket, _ := transportLayer.(*layers.SCTP)
		srcPort = transportPacket.SrcPort.String()
	}
	var e *FlowEndpointStatistics
	if ep.AB.Value == srcPort {
		e = ep.AB
	} else {
		e = ep.BA
	}
	e.Packets += uint64(1)
	e.Bytes += uint64(len(transportLayer.LayerContents()) + len(transportLayer.LayerPayload()))
	return nil
}
예제 #2
0
func (fs *FlowStatistics) updateTransportFromGoPacket(packet *gopacket.Packet) error {
	var transportLayer gopacket.Layer
	transportLayer = (*packet).Layer(layers.LayerTypeTCP)
	_, ok := transportLayer.(*layers.TCP)
	ptype := FlowEndpointType_TCPPORT
	if !ok {
		transportLayer = (*packet).Layer(layers.LayerTypeUDP)
		_, ok := transportLayer.(*layers.UDP)
		ptype = FlowEndpointType_UDPPORT
		if !ok {
			transportLayer = (*packet).Layer(layers.LayerTypeSCTP)
			_, ok := transportLayer.(*layers.SCTP)
			ptype = FlowEndpointType_SCTPPORT
			if !ok {
				return errors.New("Unable to decode the transport layer")
			}
		}
	}

	ep := fs.Endpoints[ptype.Value()]
	var srcPort string

	switch ptype {
	case FlowEndpointType_TCPPORT:
		transportPacket, _ := transportLayer.(*layers.TCP)
		srcPort = transportPacket.SrcPort.String()
	case FlowEndpointType_UDPPORT:
		transportPacket, _ := transportLayer.(*layers.UDP)
		srcPort = transportPacket.SrcPort.String()
	case FlowEndpointType_SCTPPORT:
		transportPacket, _ := transportLayer.(*layers.SCTP)
		srcPort = transportPacket.SrcPort.String()
	}
	var e *FlowEndpointStatistics
	if ep.AB.Value == srcPort {
		e = ep.AB
	} else {
		e = ep.BA
	}
	e.Packets += uint64(1)
	e.Bytes += uint64(len(transportLayer.LayerContents()) + len(transportLayer.LayerPayload()))
	return nil
}
예제 #3
0
파일: action.go 프로젝트: hkwi/gopenflow
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
}