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