func (d *DecoderStruct) process( packet *protos.Packet, layerType gopacket.LayerType, ) error { switch layerType { case layers.LayerTypeIPv4: debugf("IPv4 packet") packet.Tuple.Src_ip = d.ip4.SrcIP packet.Tuple.Dst_ip = d.ip4.DstIP packet.Tuple.Ip_length = 4 case layers.LayerTypeIPv6: debugf("IPv6 packet") packet.Tuple.Src_ip = d.ip6.SrcIP packet.Tuple.Dst_ip = d.ip6.DstIP packet.Tuple.Ip_length = 16 case layers.LayerTypeICMPv4: debugf("ICMPv4 packet") packet.Payload = d.icmp4.Payload packet.Tuple.ComputeHashebles() d.icmp4Proc.ProcessICMPv4(&d.icmp4, packet) case layers.LayerTypeICMPv6: debugf("ICMPv6 packet") packet.Payload = d.icmp6.Payload packet.Tuple.ComputeHashebles() d.icmp6Proc.ProcessICMPv6(&d.icmp6, packet) case layers.LayerTypeUDP: debugf("UDP packet") packet.Tuple.Src_port = uint16(d.udp.SrcPort) packet.Tuple.Dst_port = uint16(d.udp.DstPort) packet.Payload = d.udp.Payload packet.Tuple.ComputeHashebles() d.udpProc.Process(packet) case layers.LayerTypeTCP: debugf("TCP packet") packet.Tuple.Src_port = uint16(d.tcp.SrcPort) packet.Tuple.Dst_port = uint16(d.tcp.DstPort) packet.Payload = d.tcp.Payload if len(packet.Payload) == 0 && !d.tcp.FIN { // We have no use for this atm. debugf("Ignore empty non-FIN packet") break } packet.Tuple.ComputeHashebles() d.tcpProc.Process(&d.tcp, packet) } return nil }
func (d *DecoderStruct) onICMPv6(packet *protos.Packet) { if d.icmp6Proc != nil { packet.Payload = d.icmp6.Payload packet.Tuple.ComputeHashebles() d.icmp6Proc.ProcessICMPv6(d.flowID, &d.icmp6, packet) } }
func (d *Decoder) onICMPv4(packet *protos.Packet) { if d.icmp4Proc != nil { packet.Payload = d.icmp4.Payload packet.Tuple.ComputeHashebles() d.icmp4Proc.ProcessICMPv4(d.flowID, &d.icmp4, packet) } }
func (d *DecoderStruct) onUDP(packet *protos.Packet) { src := uint16(d.udp.SrcPort) dst := uint16(d.udp.DstPort) id := d.flowID if id != nil { d.flowID.AddUDP(src, dst) } packet.Tuple.SrcPort = src packet.Tuple.DstPort = dst packet.Payload = d.udp.Payload packet.Tuple.ComputeHashebles() d.udpProc.Process(id, packet) }
func (d *DecoderStruct) onTCP(packet *protos.Packet) { src := uint16(d.tcp.SrcPort) dst := uint16(d.tcp.DstPort) id := d.flowID if id != nil { id.AddTCP(src, dst) } packet.Tuple.SrcPort = src packet.Tuple.DstPort = dst packet.Payload = d.tcp.Payload if id == nil && len(packet.Payload) == 0 && !d.tcp.FIN { // We have no use for this atm. debugf("Ignore empty non-FIN packet") return } packet.Tuple.ComputeHashebles() d.tcpProc.Process(id, &d.tcp, packet) }
func (tcp *Tcp) Process(id *flows.FlowID, tcphdr *layers.TCP, pkt *protos.Packet) { // This Recover should catch all exceptions in // protocol modules. defer logp.Recover("Process tcp exception") stream, created := tcp.getStream(pkt) if stream.conn == nil { return } conn := stream.conn if id != nil { id.AddConnectionID(uint64(conn.id)) } if isDebug { debugf("tcp flow id: %p", id) } if len(pkt.Payload) == 0 && !tcphdr.FIN { // return early if packet is not interesting. Still need to find/create // stream first in order to update the TCP stream timer return } tcpStartSeq := tcphdr.Seq tcpSeq := tcpStartSeq + uint32(len(pkt.Payload)) lastSeq := conn.lastSeq[stream.dir] if isDebug { debugf("pkt.start_seq=%v pkt.last_seq=%v stream.last_seq=%v (len=%d)", tcpStartSeq, tcpSeq, lastSeq, len(pkt.Payload)) } if len(pkt.Payload) > 0 && lastSeq != 0 { if tcpSeqBeforeEq(tcpSeq, lastSeq) { if isDebug { debugf("Ignoring retransmitted segment. pkt.seq=%v len=%v stream.seq=%v", tcphdr.Seq, len(pkt.Payload), lastSeq) } return } switch tcpSeqCompare(lastSeq, tcpStartSeq) { case seqLT: // lastSeq < tcpStartSeq => Gap in tcp stream detected if created { break } gap := int(tcpStartSeq - lastSeq) debugf("Gap in tcp stream. last_seq: %d, seq: %d, gap: %d", lastSeq, tcpStartSeq, gap) drop := stream.gapInStream(gap) if drop { if isDebug { debugf("Dropping connection state because of gap") } droppedBecauseOfGaps.Add(1) // drop application layer connection state and // update stream_id for app layer analysers using stream_id for lookups conn.id = tcp.getId() conn.data = nil } case seqGT: // lastSeq > tcpStartSeq => overlapping TCP segment detected. shrink packet delta := lastSeq - tcpStartSeq if isDebug { debugf("Overlapping tcp segment. last_seq %d, seq: %d, delta: %d", lastSeq, tcpStartSeq, delta) } pkt.Payload = pkt.Payload[delta:] tcphdr.Seq += delta } } conn.lastSeq[stream.dir] = tcpSeq stream.addPacket(pkt, tcphdr) }
func (decoder *DecoderStruct) DecodePacketData(data []byte, ci *gopacket.CaptureInfo) { var err error var packet protos.Packet err = decoder.Parser.DecodeLayers(data, &decoder.decoded) if err != nil { // Ignore UnsupportedLayerType errors that can occur while parsing // UDP packets. lastLayer := decoder.decoded[len(decoder.decoded)-1] _, unsupported := err.(gopacket.UnsupportedLayerType) if !(unsupported && lastLayer == layers.LayerTypeUDP) { logp.Debug("pcapread", "Decoding error: %s", err) return } } has_icmp4 := false has_icmp6 := false has_tcp := false has_udp := false for _, layerType := range decoder.decoded { switch layerType { case layers.LayerTypeIPv4: logp.Debug("ip", "IPv4 packet") packet.Tuple.Src_ip = decoder.ip4.SrcIP packet.Tuple.Dst_ip = decoder.ip4.DstIP packet.Tuple.Ip_length = 4 case layers.LayerTypeIPv6: logp.Debug("ip", "IPv6 packet") packet.Tuple.Src_ip = decoder.ip6.SrcIP packet.Tuple.Dst_ip = decoder.ip6.DstIP packet.Tuple.Ip_length = 16 case layers.LayerTypeICMPv4: logp.Debug("ip", "ICMPv4 packet") has_icmp4 = true case layers.LayerTypeICMPv6: logp.Debug("ip", "ICMPv6 packet") has_icmp6 = true case layers.LayerTypeTCP: logp.Debug("ip", "TCP packet") packet.Tuple.Src_port = uint16(decoder.tcp.SrcPort) packet.Tuple.Dst_port = uint16(decoder.tcp.DstPort) has_tcp = true case layers.LayerTypeUDP: logp.Debug("ip", "UDP packet") packet.Tuple.Src_port = uint16(decoder.udp.SrcPort) packet.Tuple.Dst_port = uint16(decoder.udp.DstPort) packet.Payload = decoder.udp.Payload has_udp = true case gopacket.LayerTypePayload: packet.Payload = decoder.payload } } packet.Ts = ci.Timestamp packet.Tuple.ComputeHashebles() if has_udp { decoder.udpProc.Process(&packet) } else if has_tcp { if len(packet.Payload) == 0 && !decoder.tcp.FIN { // We have no use for this atm. logp.Debug("pcapread", "Ignore empty non-FIN packet") return } decoder.tcpProc.Process(&decoder.tcp, &packet) } else if has_icmp4 { decoder.icmp4Proc.ProcessICMPv4(&decoder.icmp4, &packet) } else if has_icmp6 { decoder.icmp6Proc.ProcessICMPv6(&decoder.icmp6, &packet) } }