/* protos must contain a UDP or TCP layer on top of IPv4 */ func forgeTestPacket(t *testing.T, seed int64, protos ...ProtocolType) *gopacket.Packet { rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} var protoStack []gopacket.SerializableLayer for i, proto := range protos { switch proto { case ETH: ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, EthernetType: layers.EthernetTypeIPv4, } protoStack = append(protoStack, ethernetLayer) case IPv4: ipv4Layer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } switch protos[i+1] { case TCP: ipv4Layer.Protocol = layers.IPProtocolTCP case UDP: ipv4Layer.Protocol = layers.IPProtocolUDP } protoStack = append(protoStack, ipv4Layer) case TCP: tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))), DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, tcpLayer) case UDP: udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(byte(rnd.Intn(0x10000))), DstPort: layers.UDPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, udpLayer) default: t.Log("forgeTestPacket : Unsupported protocol ", proto) } } protoStack = append(protoStack, gopacket.Payload(rawBytes)) buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buffer, options, protoStack...) if err != nil { t.Fail() } gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default) return &gpacket }
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 (p *reusingProcessor) ProcessAll() (err error) { defer errs.PassE(&err) pd := NewUdpDstPortPayloadDetector() for port := 30100; port < 30200; port++ { pd.addPortMap(layers.UDPPort(port), bats.LayerTypeBSU) } for port := 51000; port < 51100; port++ { pd.addPortMap(layers.UDPPort(port), miax.LayerTypeMachTop) } for port := 18000; port < 18010; port++ { pd.addPortMap(layers.UDPPort(port), nasdaq.LayerTypeMoldUDP64) } pmlf := &payloadMuxLayerFactory{} pmlf.AddDetector(pd) parser := packet.NewReusingLayerParser(layers.LayerTypeEthernet) parser.AddDecodingLayerFactory(EthernetLayerFactory) parser.AddDecodingLayerFactory(Dot1QLayerFactory) parser.AddDecodingLayerFactory(IPv4LayerFactory) parser.AddDecodingLayerFactory(UDPLayerFactory) parser.AddDecodingLayerFactory(TcpIgnoreLayerFactory) parser.AddDecodingLayerFactory(pmlf) parser.AddDecodingLayerFactory(miax.MachTopLayerFactory) parser.AddDecodingLayerFactory(miax.MachLayerFactory) parser.AddDecodingLayerFactory(miax.TomLayerFactory) parser.AddDecodingLayerFactory(bats.BSULayerFactory) parser.AddDecodingLayerFactory(bats.PitchLayerFactory) parser.AddDecodingLayerFactory(nasdaq.MoldUDP64LayerFactory) parser.AddDecodingLayerFactory(nasdaq.MoldUDP64MessageBlockLayerFactory) parser.AddDecodingLayerFactory(nasdaq.IttoLayerFactory) packetNumLimit := -1 if p.packetNumLimit > 0 { packetNumLimit = p.packetNumLimit } var decoded []gopacket.DecodingLayer pmlf.SetDecodedLayers(&decoded) for packetNum := 0; packetNum != packetNumLimit; packetNum++ { //log.Printf("packetNum: %d\n", packetNum) data, ci, err := p.obtainer.ZeroCopyReadPacketData() if err == io.EOF { break } errs.CheckE(err) errs.CheckE(parser.DecodeLayers(data, &decoded)) errs.CheckE(p.ProcessPacket(data, ci, decoded)) } return }
func (sender *RawUDPSender) Send(msg []byte) error { payload := gopacket.Payload(msg) sender.udpHeader.DstPort = layers.UDPPort(sender.conn.RemoteUDPAddr().Port) err := gopacket.SerializeLayers(sender.ipBuf, sender.opts, sender.udpHeader, &payload) if err != nil { return err } packet := sender.ipBuf.Bytes() _, err = sender.socket.Write(packet) if err == nil || PosixError(err) != syscall.EMSGSIZE { return err } f, err := sender.socket.File() if err != nil { return err } defer f.Close() fd := int(f.Fd()) log.Println("EMSGSIZE on send, expecting PMTU update (IP packet was", len(packet), "bytes, payload was", len(msg), "bytes)") pmtu, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MTU) if err != nil { return err } return MsgTooBigError{PMTU: pmtu} }
/* FUNCTION: craftPacket(data []byte, ip string, port uint16, payload []byte) []byte RETURNS: []byte, byte array containing packet data created ARGUMENTS: []byte data - data to be placed in the source port string ip - address to place in the dst ip of the ip layer uint16 port - destination port of udp header []byte payload - udp payload to be passed in ABOUT: Crafts a packet with a IP, ethernet and UDP header. Covertly inserts data into the source port and appends the specified payload. */ func craftPacket(data []byte, ip string, port uint16, payload []byte) []byte { ethernetLayer := &layers.Ethernet{ SrcMAC: localmac, DstMAC: destmac, EthernetType: layers.EthernetTypeIPv4, } ipLayer := &layers.IPv4{ Version: 4, IHL: 5, TOS: 0, Length: 20, Id: 2, Flags: layers.IPv4DontFragment, FragOffset: 0, TTL: 255, Protocol: layers.IPProtocolUDP, Checksum: 0, SrcIP: localip, DstIP: net.ParseIP(ip), } val := binary.BigEndian.Uint16(data) udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(MAX_PORT - val), DstPort: layers.UDPPort(port), Length: 16, } err := udpLayer.SetNetworkLayerForChecksum(ipLayer) checkError(err) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } err = gopacket.SerializeLayers(buf, opts, ethernetLayer, ipLayer, udpLayer, gopacket.Payload(payload)) checkError(err) return buf.Bytes() }
func (p *GoPacketProbesHandler) RegisterProbe(n *graph.Node, capture *api.Capture, ft *flow.Table) error { name, ok := n.Metadata()["Name"] if !ok || name == "" { return fmt.Errorf("No name for node %v", n) } encapType, ok := n.Metadata()["EncapType"] if !ok || encapType == "" { return fmt.Errorf("No EncapType for node %v", n) } tid, ok := n.Metadata()["TID"] if !ok { return fmt.Errorf("No TID for node %v", n) } id := string(n.ID) ifName := name.(string) if _, ok = p.probes[id]; ok { return fmt.Errorf("Already registered %s", ifName) } port, ok := n.Metadata()["MPLSUDPPort"].(int) if ok { // All gopacket instance of this agent will classify UDP packets coming // from UDP port MPLSUDPPort as MPLS whatever the source interface layers.RegisterUDPPortLayerType(layers.UDPPort(port), layers.LayerTypeMPLS) logging.GetLogger().Infof("MPLSoUDP port: %v", port) } probe := &GoPacketProbe{ NodeTID: tid.(string), state: common.StoppedState, flowTable: ft, } p.probesLock.Lock() p.probes[id] = probe p.probesLock.Unlock() p.wg.Add(1) go func() { defer p.wg.Done() probe.run(p.graph, n, capture) }() return nil }
func newUDPSenderDF(localIP net.IP, localPort int) *udpSenderDF { return &udpSenderDF{ ipBuf: gopacket.NewSerializeBuffer(), opts: gopacket.SerializeOptions{ FixLengths: true, // UDP header is calculated with a phantom IP // header. Yes, it's totally nuts. Thankfully, // for UDP over IPv4, the checksum is // optional. It's not optional for IPv6, but // we'll ignore that for now. TODO ComputeChecksums: false, }, udpHeader: &layers.UDP{SrcPort: layers.UDPPort(localPort)}, localIP: localIP, } }
func ianaPort(layerType gopacket.LayerType, port uint16) string { if layerType == layers.LayerTypeTCP { proto, in := layers.TCPPortNames[layers.TCPPort(port)] if in { return fmt.Sprintf("%s (TCP)", proto) } else { return "N/A (TCP)" } } else { proto, in := layers.UDPPortNames[layers.UDPPort(port)] if in { return fmt.Sprintf("%s (UDP)", proto) } else { return "N/A (UDP)" } } }
func TestFlowEncaspulationMplsUdp(t *testing.T) { layers.RegisterUDPPortLayerType(layers.UDPPort(444), layers.LayerTypeMPLS) table := NewTable(nil, nil) packet := forgeTestPacket(t, 64, false, ETH, IPv4, UDP_MPLS, MPLS, IPv4, TCP) flowPackets := FlowPacketsFromGoPacket(packet, 0) table.FlowPacketsToFlow(flowPackets) flows := table.GetFlows(nil).GetFlows() if len(flows) != 2 { t.Error("An MPLSoUDP packet must generate 2 flows") } flows = sortFlowByRelationship(flows) if flows[0].LayersPath != "Ethernet/IPv4/UDP/MPLS" || flows[1].LayersPath != "IPv4/TCP/Payload" { t.Errorf("Flows LayersPath must be Ethernet/IPv4/UDP/MPLS | IPv4/TCP/Payload") } }
func (sender *udpSenderDF) send(msg []byte, raddr *net.UDPAddr) error { // Ensure we have a socket sending to the right IP address if sender.socket == nil || !bytes.Equal(sender.remoteIP, raddr.IP) { sender.remoteIP = raddr.IP if err := sender.dial(); err != nil { return err } } sender.udpHeader.DstPort = layers.UDPPort(raddr.Port) payload := gopacket.Payload(msg) err := gopacket.SerializeLayers(sender.ipBuf, sender.opts, sender.udpHeader, &payload) if err != nil { return err } packet := sender.ipBuf.Bytes() _, err = sender.socket.Write(packet) if err == nil || PosixError(err) != syscall.EMSGSIZE { return err } f, err := sender.socket.File() if err != nil { return err } defer f.Close() log.Print("EMSGSIZE on send, expecting PMTU update (IP packet was ", len(packet), " bytes, payload was ", len(msg), " bytes)") pmtu, err := syscall.GetsockoptInt(int(f.Fd()), syscall.IPPROTO_IP, syscall.IP_MTU) if err != nil { return err } return msgTooBigError{underlayPMTU: pmtu} }
func (c *Capture) StartFromPCAP(file string, port int) (err error) { handle, err := pcap.OpenOffline(file) if err != nil { log.Fatal("PCAP OpenOffline error:", err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) for packet := range packetSource.Packets() { udpLayer := packet.Layer(layers.LayerTypeUDP) udp, ok := udpLayer.(*layers.UDP) if ok && udp != nil { if udp.DstPort != layers.UDPPort(port) { m := NewRawMessage(udp.Payload) c.processDefault(m) } } } return }
func NewRawUDPSender(conn *LocalConnection) (*RawUDPSender, error) { ipSocket, err := dialIP(conn) if err != nil { return nil, err } udpHeader := &layers.UDP{SrcPort: layers.UDPPort(conn.Router.Port)} ipBuf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, // UDP header is calculated with a phantom IP // header. Yes, it's totally nuts. Thankfully, for UDP // over IPv4, the checksum is optional. It's not // optional for IPv6, but we'll ignore that for // now. TODO ComputeChecksums: false} return &RawUDPSender{ ipBuf: ipBuf, opts: opts, udpHeader: udpHeader, socket: ipSocket, conn: conn}, 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) }
/* protos must contain a UDP or TCP layer on top of IPv4 */ func forgeTestPacket(t *testing.T, seed int64, swap bool, protos ...ProtocolType) *gopacket.Packet { rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} var protoStack []gopacket.SerializableLayer for i, proto := range protos { switch proto { case GRE: greLayer := &layers.GRE{} switch protos[i+1] { case IPv4: greLayer.Protocol = layers.EthernetTypeIPv4 case IPv6: greLayer.Protocol = layers.EthernetTypeIPv6 default: t.Error(fmt.Sprintf("Protocol %s can not be encapsulated in GRE", protos[i+1])) } protoStack = append(protoStack, greLayer) case ETH: ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, EthernetType: layers.EthernetTypeIPv4, } if swap { ethernetLayer.SrcMAC, ethernetLayer.DstMAC = ethernetLayer.DstMAC, ethernetLayer.SrcMAC } protoStack = append(protoStack, ethernetLayer) case IPv4: ipv4Layer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } switch protos[i+1] { case TCP: ipv4Layer.Protocol = layers.IPProtocolTCP case UDP: ipv4Layer.Protocol = layers.IPProtocolUDP case GRE: ipv4Layer.Protocol = layers.IPProtocolGRE } if swap { ipv4Layer.SrcIP, ipv4Layer.DstIP = ipv4Layer.DstIP, ipv4Layer.SrcIP } protoStack = append(protoStack, ipv4Layer) case TCP: tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))), DstPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))), } if swap { tcpLayer.SrcPort, tcpLayer.DstPort = tcpLayer.DstPort, tcpLayer.SrcPort } protoStack = append(protoStack, tcpLayer) case UDP: udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))), DstPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))), } if swap { udpLayer.SrcPort, udpLayer.DstPort = udpLayer.DstPort, udpLayer.SrcPort } protoStack = append(protoStack, udpLayer) default: t.Log("forgeTestPacket : Unsupported protocol ", proto) } } protoStack = append(protoStack, gopacket.Payload(rawBytes)) buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buffer, options, protoStack...) if err != nil { t.Fail() } firstLayerType := layers.LayerTypeEthernet switch protos[0] { case IPv4: firstLayerType = layers.LayerTypeIPv4 case IPv6: firstLayerType = layers.LayerTypeIPv6 } gpacket := gopacket.NewPacket(buffer.Bytes(), firstLayerType, gopacket.Default) return &gpacket }
func (vnet *VNET) handleUDPForward(pkt *Packet, now time.Time) { defer pkt.Release() // fmt.Printf("UDP: %08x %s\n", pkt.Flags, pkt.String()) var err error if bytes.Equal(pkt.Eth.DstMAC, layers.EthernetBroadcast[:]) { // ignore return } if pkt.DstHost == nil { // ignore return } if !pkt.DstHost.Up { log.Printf("destination is down: %s", pkt.DstHost.Name) // ignore return } var ( srcIP net.IP dstIP net.IP srcPort = uint16(pkt.UDP.SrcPort) dstPort = uint16(pkt.UDP.DstPort) ) if pkt.IPv4 != nil { srcIP = CloneIP(pkt.IPv4.SrcIP.To16()) dstIP = CloneIP(pkt.IPv4.DstIP.To16()) } else if pkt.IPv6 != nil { srcIP = CloneIP(pkt.IPv6.SrcIP.To16()) dstIP = CloneIP(pkt.IPv6.DstIP.To16()) } else { log.Printf("invalid protocol") // ignore return } route := vnet.routes.GetTable().Lookup( protocols.UDP, srcIP, dstIP, srcPort, dstPort) if route == nil { rule, found := vnet.rules.GetTable().Lookup(protocols.UDP, pkt.DstHost.ID, dstPort) if !found { log.Printf("no rule") // ignore return } var ruleDstIP = rule.DstIP if ruleDstIP == nil { gateway := vnet.hosts.GetTable().LookupByName("gateway") if gateway == nil || !gateway.Up { log.Printf("no gateway") // ignore return } if dstIP.To4() != nil { if len(gateway.IPv4Addrs) > 0 { ruleDstIP = gateway.IPv4Addrs[0] } } else { if len(gateway.IPv6Addrs) > 0 { ruleDstIP = gateway.IPv6Addrs[0] } } } if ruleDstIP == nil { log.Printf("no destination ip") // ignore return } var r routes.Route r.Protocol = protocols.UDP r.HostID = pkt.DstHost.ID r.SetInboundSource(srcIP, srcPort) r.SetInboundDestination(dstIP, dstPort) r.SetOutboundDestination(ruleDstIP, rule.DstPort) route, err = vnet.routes.AddRoute(&r) if err != nil { // ignore log.Printf("UDP/error: %s", err) return } } if route == nil { log.Printf("no route") // ignore return } var ( eth layers.Ethernet udp layers.UDP ) eth = *pkt.Eth eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC udp = *pkt.UDP udp.SrcPort = layers.UDPPort(route.Outbound.SrcPort) udp.DstPort = layers.UDPPort(route.Outbound.DstPort) if route.Outbound.DstIP.To4() != nil { ip := layers.IPv4{ SrcIP: route.Outbound.SrcIP.To4(), DstIP: route.Outbound.DstIP.To4(), Version: 4, Protocol: layers.IPProtocolUDP, TTL: 64, } udp.SetNetworkLayerForChecksum(&ip) err = vnet.writePacket( ð, &ip, &udp, gopacket.Payload(pkt.UDP.Payload)) if err != nil { log.Printf("UDP/error: %s", err) return } } else { ip := layers.IPv6{ SrcIP: route.Outbound.SrcIP.To16(), DstIP: route.Outbound.DstIP.To16(), Version: 4, NextHeader: layers.IPProtocolUDP, } udp.SetNetworkLayerForChecksum(&ip) err = vnet.writePacket( ð, &ip, &udp, gopacket.Payload(pkt.UDP.Payload)) if err != nil { log.Printf("UDP/error: %s", err) return } } route.RoutedPacket(now, len(pkt.buf)) }
func (h *dnsStream) creatPacket(msg_buf []byte, nomalPack chan gopacket.Packet) { var sourcePort, DesPort int16 //read the port from tranport flow b_buf := bytes.NewBuffer(h.transport.Src().Raw()) binary.Read(b_buf, binary.BigEndian, &sourcePort) b_buf = bytes.NewBuffer(h.transport.Dst().Raw()) binary.Read(b_buf, binary.BigEndian, &DesPort) //new a UDP layer udpLayer := layers.UDP{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: msg_buf, }, SrcPort: layers.UDPPort(sourcePort), DstPort: layers.UDPPort(DesPort), Length: 1024, Checksum: 30026, } UDPNewSerializBuffer := gopacket.NewSerializeBuffer() // this buffer could be used as a payload of IP layer udpBuffer, _ := UDPNewSerializBuffer.PrependBytes(len(msg_buf)) copy(udpBuffer, msg_buf) ops := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } if h.net.EndpointType() == layers.EndpointIPv4 { ip_checksum := layers.IPv4{} ip_checksum.Version = 4 ip_checksum.TTL = 0 ip_checksum.SrcIP = h.net.Src().Raw() ip_checksum.DstIP = h.net.Dst().Raw() udpLayer.SetNetworkLayerForChecksum(&ip_checksum) } else { ip6_checksum := layers.IPv6{} ip6_checksum.Version = 6 ip6_checksum.NextHeader = layers.IPProtocolNoNextHeader ip6_checksum.HopLimit = 0 ip6_checksum.SrcIP = h.net.Src().Raw() ip6_checksum.DstIP = h.net.Dst().Raw() udpLayer.SetNetworkLayerForChecksum(&ip6_checksum) } err := udpLayer.SerializeTo(UDPNewSerializBuffer, ops) if err != nil { fmt.Print("error in create udp Layer") return //err = nil // need err handle there } fmt.Println("finished creat udplayer, the length is ", udpLayer.Length) if h.net.EndpointType() == layers.EndpointIPv4 { // if it is from ipv4, construct a ipv4 layer ip := layers.IPv4{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: UDPNewSerializBuffer.Bytes(), }, Version: 4, IHL: 0, TOS: 0, Length: 0, Id: 0, Flags: 0, FragOffset: 0, TTL: 0, Protocol: layers.IPProtocolUDP, Checksum: 0, SrcIP: h.net.Src().Raw(), DstIP: h.net.Dst().Raw(), Options: []layers.IPv4Option{}, Padding: []byte{}, } //serialize it and use the serilize buffer to new packet IPserializeBuffer := gopacket.NewSerializeBuffer() ipBuffer, _ := IPserializeBuffer.PrependBytes(len(UDPNewSerializBuffer.Bytes())) copy(ipBuffer, UDPNewSerializBuffer.Bytes()) err = ip.SerializeTo(IPserializeBuffer, ops) if err != nil { fmt.Print("error in create ipv4 Layer") return //err = nil // need err handle there } fmt.Println("finished creat ip, the length is ", ip.Length) resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv4, gopacket.Default) resultPack.Metadata().CaptureLength = len(resultPack.Data()) resultPack.Metadata().Length = len(resultPack.Data()) //seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value nomalPack <- resultPack return } else if h.net.EndpointType() == layers.EndpointIPv6 { // if it is in IPV6 contruct ipv6 packet ip := layers.IPv6{ BaseLayer: layers.BaseLayer{ Contents: []byte{}, Payload: UDPNewSerializBuffer.Bytes(), }, Version: 6, TrafficClass: 0, FlowLabel: 0, Length: 0, NextHeader: layers.IPProtocolNoNextHeader, //no sure what next header should be used there HopLimit: 0, SrcIP: h.net.Src().Raw(), DstIP: h.net.Dst().Raw(), HopByHop: nil, // hbh will be pointed to by HopByHop if that layer exists. } IPserializeBuffer := gopacket.NewSerializeBuffer() err := ip.SerializeTo(IPserializeBuffer, ops) if err != nil { fmt.Printf("error in creat IPV6 Layer") return } fmt.Println("finished creat ip, the length is ", ip.Length) resultPack := gopacket.NewPacket(IPserializeBuffer.Bytes(), layers.LayerTypeIPv6, gopacket.Default) resultPack.Metadata().CaptureLength = len(resultPack.Data()) resultPack.Metadata().Length = len(resultPack.Data()) //seems the capture length is 0 so the pcapwrite cannot write it, try to give them a write value nomalPack <- resultPack return } else { return //unknown network just return? } }
func (vnet *VNET) handleDHCPOffer(pkt *Packet, offer *dhcp.Message) { if offer.YourIPAddress == nil { return } msg := &dhcp.Message{} msg.ClientMAC = vnet.system.ControllerMAC() msg.Type = dhcp.MessageTypeRequest msg.HardwareType = dhcp.MessageHardwareTypeEthernet msg.HardwareAddressLength = 6 msg.Hops = 0 msg.TransactionID = offer.TransactionID msg.Options = map[uint8]*dhcp.Option{ dhcp.OptionCodeDHCPMessageType: { Value: []byte{dhcp.DHCPMessageTypeRequest}, }, dhcp.OptionCodeDHCPClientidentifier: { Value: append([]byte{1}, msg.ClientMAC[:6]...), }, dhcp.OptionCodeDHCPRequestedIPAddress: { Value: offer.YourIPAddress.To4(), }, dhcp.OptionCodeDHCPServerIdentifier: offer.Options[dhcp.OptionCodeDHCPServerIdentifier], dhcp.OptionCodeDHCPMaximumMessageSize: { Value: []byte{2, 64}, // 576 }, dhcp.OptionCodeDHCPParameterRequestList: { Value: []byte{ dhcp.OptionCodeSubnetMask, dhcp.OptionCodeRouter, dhcp.OptionCodeDomainNameServer, dhcp.OptionCodeHostName, dhcp.OptionCodeDomainName, dhcp.OptionCodeBroadcastAddress, dhcp.OptionCodeNetworkTimeProtocolServers, }, }, dhcp.OptionCodeDHCPVendorclassidentifier: { Value: []byte("swtchbrd 1.23.1"), }, dhcp.OptionCodeEnd: {}, } ipv4 := &layers.IPv4{ SrcIP: net.IPv4(0, 0, 0, 0), DstIP: net.IPv4(255, 255, 255, 255), Version: 4, Protocol: layers.IPProtocolUDP, TTL: 64, } udp := &layers.UDP{ SrcPort: layers.UDPPort(68), DstPort: layers.UDPPort(67), } udp.SetNetworkLayerForChecksum(ipv4) err := vnet.writePacket( &layers.Ethernet{ SrcMAC: msg.ClientMAC, DstMAC: layers.EthernetBroadcast, EthernetType: layers.EthernetTypeIPv4, }, ipv4, udp, gopacket.Payload(writeDHCPMessage(msg))) if err != nil { log.Printf("DCHP/error: %s", err) return } return }
// String returns the port as "number(name)" if there's a well-known port name, // or just "number" if there isn't. Well-known names are stored in // UDPPortNames. func (a UDPPort) String() string { if name, ok := layers.UDPPortNames[layers.UDPPort(a)]; ok { return fmt.Sprintf("%d(%s)", a, name) } return strconv.Itoa(int(a)) }
// Given an EvePacket, convert the payload to a PCAP faking out the // headers as best we can. // // A buffer containing the 1 packet pcap file will be returned. func EvePayloadToPcap(event *EveEvent) ([]byte, error) { buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } payloadLayer := gopacket.Payload(event.Payload.Bytes()) payloadLayer.SerializeTo(buffer, options) srcIp := net.ParseIP(event.SrcIP) if srcIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.SrcIP) } dstIp := net.ParseIP(event.DstIP) if dstIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.DstIP) } proto, err := ProtoNumber(event.Proto) if err != nil { return nil, err } switch proto { case layers.IPProtocolTCP: // Could probably fake up a better TCP layer here. tcpLayer := layers.TCP{ SrcPort: layers.TCPPort(event.SrcPort), DstPort: layers.TCPPort(event.DstPort), } tcpLayer.SerializeTo(buffer, options) break case layers.IPProtocolUDP: udpLayer := layers.UDP{ SrcPort: layers.UDPPort(event.SrcPort), DstPort: layers.UDPPort(event.DstPort), } udpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv4: icmpLayer := layers.ICMPv4{ TypeCode: layers.CreateICMPv4TypeCode( event.IcmpType, event.IcmpCode), Id: 0, Seq: 0, } icmpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv6: icmp6Layer := layers.ICMPv6{ TypeCode: layers.CreateICMPv6TypeCode( event.IcmpType, event.IcmpCode), } icmp6Layer.SerializeTo(buffer, options) break default: return nil, fmt.Errorf("Unsupported protocol %d.", proto) } isIp6 := dstIp.To4() == nil if !isIp6 { ipLayer := layers.IPv4{ SrcIP: srcIp, DstIP: dstIp, Version: 4, Protocol: proto, TTL: 64, } ipLayer.SerializeTo(buffer, options) } else { ip6Layer := layers.IPv6{ Version: 6, SrcIP: srcIp, DstIP: dstIp, } ip6Layer.SerializeTo(buffer, options) } return pcap.CreatePcap(event.Timestamp.Time, buffer.Bytes(), layers.LinkTypeRaw) }