github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/ebpftracer/decoder/decoder.go (about)

     1  package decoder
     2  
     3  //go:generate go run ../../../tools/codegen/... ../events.go ../types/args.go args_decoder.go decoder
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/binary"
     8  	"errors"
     9  	"fmt"
    10  	"net"
    11  	"net/netip"
    12  	"strings"
    13  
    14  	castpb "github.com/castai/kvisor/api/v1/runtime"
    15  	"github.com/castai/kvisor/pkg/ebpftracer/events"
    16  	"github.com/castai/kvisor/pkg/ebpftracer/types"
    17  	"github.com/castai/kvisor/pkg/logging"
    18  	"github.com/castai/kvisor/pkg/net/packet"
    19  	"github.com/google/gopacket"
    20  	"github.com/google/gopacket/layers"
    21  )
    22  
    23  type Decoder struct {
    24  	log    *logging.Logger
    25  	buffer []byte
    26  	cursor int
    27  }
    28  
    29  var ErrBufferTooShort = errors.New("can't read context from buffer: buffer too short")
    30  
    31  // New creates and initializes a new decoder using rawBuffer as its initial content.
    32  // The decoder takes ownership of rawBuffer, and the caller should not use rawBuffer after this call.
    33  // New is intended to prepare a buffer to read existing data from it, translating it to protocol defined structs.
    34  // The protocol is specific between the Trace eBPF program and the Tracee-eBPF user space application.
    35  func NewEventDecoder(log *logging.Logger, rawBuffer []byte) *Decoder {
    36  	return &Decoder{
    37  		log:    log,
    38  		buffer: rawBuffer,
    39  		cursor: 0,
    40  	}
    41  }
    42  
    43  func (decoder *Decoder) SeekForward(amount int) {
    44  	decoder.cursor += amount
    45  }
    46  
    47  // BuffLen returns the total length of the buffer owned by decoder.
    48  func (decoder *Decoder) BuffLen() int {
    49  	return len(decoder.buffer)
    50  }
    51  
    52  // ReadAmountBytes returns the total amount of bytes that decoder has read from its buffer up until now.
    53  func (decoder *Decoder) ReadAmountBytes() int {
    54  	return decoder.cursor
    55  }
    56  
    57  func (decoder *Decoder) DecodeSignalContext(ctx *types.SignalContext) error {
    58  	offset := decoder.cursor
    59  	if len(decoder.buffer[offset:]) < ctx.GetSizeBytes() {
    60  		return fmt.Errorf("signal context buffer size [%d] smaller than %d", len(decoder.buffer[offset:]), ctx.GetSizeBytes())
    61  	}
    62  
    63  	ctx.EventID = events.ID(binary.LittleEndian.Uint32(decoder.buffer[offset : offset+4]))
    64  
    65  	decoder.cursor += ctx.GetSizeBytes()
    66  
    67  	return nil
    68  }
    69  
    70  // DecodeContext translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.eventContext struct.
    71  func (decoder *Decoder) DecodeContext(ctx *types.EventContext) error {
    72  	offset := decoder.cursor
    73  	if len(decoder.buffer[offset:]) < ctx.GetSizeBytes() {
    74  		return fmt.Errorf("context buffer size [%d] smaller than %d", len(decoder.buffer[offset:]), ctx.GetSizeBytes())
    75  	}
    76  
    77  	// event_context start
    78  	ctx.Ts = binary.LittleEndian.Uint64(decoder.buffer[offset : offset+8])
    79  
    80  	// task_context start
    81  	ctx.StartTime = binary.LittleEndian.Uint64(decoder.buffer[offset+8 : offset+16])
    82  	ctx.CgroupID = binary.LittleEndian.Uint64(decoder.buffer[offset+16 : offset+24])
    83  	ctx.Pid = binary.LittleEndian.Uint32(decoder.buffer[offset+24 : offset+28])
    84  	ctx.Tid = binary.LittleEndian.Uint32(decoder.buffer[offset+28 : offset+32])
    85  	ctx.Ppid = binary.LittleEndian.Uint32(decoder.buffer[offset+32 : offset+36])
    86  	ctx.HostPid = binary.LittleEndian.Uint32(decoder.buffer[offset+36 : offset+40])
    87  	ctx.HostTid = binary.LittleEndian.Uint32(decoder.buffer[offset+40 : offset+44])
    88  	ctx.HostPpid = binary.LittleEndian.Uint32(decoder.buffer[offset+44 : offset+48])
    89  	ctx.NodeHostPid = binary.LittleEndian.Uint32(decoder.buffer[offset+48 : offset+52])
    90  	ctx.Uid = binary.LittleEndian.Uint32(decoder.buffer[offset+52 : offset+56])
    91  	ctx.MntID = binary.LittleEndian.Uint32(decoder.buffer[offset+56 : offset+60])
    92  	ctx.PidID = binary.LittleEndian.Uint32(decoder.buffer[offset+60 : offset+64])
    93  	_ = copy(ctx.Comm[:], decoder.buffer[offset+64:offset+80])
    94  	_ = copy(ctx.UtsName[:], decoder.buffer[offset+80:offset+96])
    95  	ctx.Flags = binary.LittleEndian.Uint32(decoder.buffer[offset+96 : offset+100])
    96  	ctx.LeaderStartTime = binary.LittleEndian.Uint64(decoder.buffer[offset+100 : offset+108])
    97  	ctx.ParentStartTime = binary.LittleEndian.Uint64(decoder.buffer[offset+108 : offset+116])
    98  	// task_context end
    99  	// 4 bytes padding
   100  
   101  	ctx.EventID = events.ID(binary.LittleEndian.Uint32(decoder.buffer[offset+120 : offset+124]))
   102  	ctx.Syscall = int32(binary.LittleEndian.Uint32(decoder.buffer[offset+124 : offset+128]))
   103  	ctx.MatchedPolicies = binary.LittleEndian.Uint64(decoder.buffer[offset+128 : offset+136])
   104  	ctx.Retval = int64(binary.LittleEndian.Uint64(decoder.buffer[offset+136 : offset+144]))
   105  	ctx.StackID = binary.LittleEndian.Uint32(decoder.buffer[offset+144 : offset+148])
   106  	ctx.ProcessorId = binary.LittleEndian.Uint16(decoder.buffer[offset+148 : offset+150])
   107  	// 2 byte padding
   108  	// event_context end
   109  
   110  	decoder.cursor += ctx.GetSizeBytes()
   111  	return nil
   112  }
   113  func (decoder *Decoder) SkipUint8() error {
   114  	readAmount := 1
   115  	offset := decoder.cursor
   116  	if len(decoder.buffer[offset:]) < readAmount {
   117  		return ErrBufferTooShort
   118  	}
   119  	decoder.cursor += readAmount
   120  	return nil
   121  }
   122  
   123  // DecodeUint8 translates data from the decoder buffer, starting from the decoder cursor, to uint8.
   124  func (decoder *Decoder) DecodeUint8(msg *uint8) error {
   125  	readAmount := 1
   126  	offset := decoder.cursor
   127  	if len(decoder.buffer[offset:]) < readAmount {
   128  		return ErrBufferTooShort
   129  	}
   130  	*msg = decoder.buffer[decoder.cursor]
   131  	decoder.cursor += readAmount
   132  	return nil
   133  }
   134  
   135  // DecodeInt8 translates data from the decoder buffer, starting from the decoder cursor, to int8.
   136  func (decoder *Decoder) DecodeInt8(msg *int8) error {
   137  	readAmount := 1
   138  	offset := decoder.cursor
   139  	if len(decoder.buffer[offset:]) < readAmount {
   140  		return ErrBufferTooShort
   141  	}
   142  	*msg = int8(decoder.buffer[offset])
   143  	decoder.cursor += readAmount
   144  	return nil
   145  }
   146  
   147  // DecodeUint16 translates data from the decoder buffer, starting from the decoder cursor, to uint16.
   148  func (decoder *Decoder) DecodeUint16(msg *uint16) error {
   149  	readAmount := 2
   150  	offset := decoder.cursor
   151  	if len(decoder.buffer[offset:]) < readAmount {
   152  		return ErrBufferTooShort
   153  	}
   154  	*msg = binary.LittleEndian.Uint16(decoder.buffer[offset : offset+readAmount])
   155  	decoder.cursor += readAmount
   156  	return nil
   157  }
   158  
   159  // DecodeUint16BigEndian translates data from the decoder buffer, starting from the decoder cursor, to uint16.
   160  func (decoder *Decoder) DecodeUint16BigEndian(msg *uint16) error {
   161  	readAmount := 2
   162  	offset := decoder.cursor
   163  	if len(decoder.buffer[offset:]) < readAmount {
   164  		return ErrBufferTooShort
   165  	}
   166  	*msg = binary.BigEndian.Uint16(decoder.buffer[offset : offset+readAmount])
   167  	decoder.cursor += readAmount
   168  	return nil
   169  }
   170  
   171  // DecodeInt16 translates data from the decoder buffer, starting from the decoder cursor, to int16.
   172  func (decoder *Decoder) DecodeInt16(msg *int16) error {
   173  	readAmount := 2
   174  	offset := decoder.cursor
   175  	if len(decoder.buffer[offset:]) < readAmount {
   176  		return ErrBufferTooShort
   177  	}
   178  	*msg = int16(binary.LittleEndian.Uint16(decoder.buffer[offset : offset+readAmount]))
   179  	decoder.cursor += readAmount
   180  	return nil
   181  }
   182  
   183  // DecodeUint32 translates data from the decoder buffer, starting from the decoder cursor, to uint32.
   184  func (decoder *Decoder) DecodeUint32(msg *uint32) error {
   185  	readAmount := 4
   186  	offset := decoder.cursor
   187  	if len(decoder.buffer[offset:]) < readAmount {
   188  		return ErrBufferTooShort
   189  	}
   190  	*msg = binary.LittleEndian.Uint32(decoder.buffer[offset : offset+readAmount])
   191  	decoder.cursor += readAmount
   192  	return nil
   193  }
   194  
   195  // DecodeUint32BigEndian translates data from the decoder buffer, starting from the decoder cursor, to uint32.
   196  func (decoder *Decoder) DecodeUint32BigEndian(msg *uint32) error {
   197  	readAmount := 4
   198  	offset := decoder.cursor
   199  	if len(decoder.buffer[offset:]) < readAmount {
   200  		return ErrBufferTooShort
   201  	}
   202  	*msg = binary.BigEndian.Uint32(decoder.buffer[offset : offset+readAmount])
   203  	decoder.cursor += readAmount
   204  	return nil
   205  }
   206  
   207  // DecodeInt32 translates data from the decoder buffer, starting from the decoder cursor, to int32.
   208  func (decoder *Decoder) DecodeInt32(msg *int32) error {
   209  	readAmount := 4
   210  	offset := decoder.cursor
   211  	if len(decoder.buffer[offset:]) < readAmount {
   212  		return ErrBufferTooShort
   213  	}
   214  	*msg = int32(binary.LittleEndian.Uint32(decoder.buffer[offset : offset+readAmount]))
   215  	decoder.cursor += readAmount
   216  	return nil
   217  }
   218  
   219  // DecodeUint64 translates data from the decoder buffer, starting from the decoder cursor, to uint64.
   220  func (decoder *Decoder) DecodeUint64(msg *uint64) error {
   221  	readAmount := 8
   222  	offset := decoder.cursor
   223  	if len(decoder.buffer[offset:]) < readAmount {
   224  		return ErrBufferTooShort
   225  	}
   226  	*msg = binary.LittleEndian.Uint64(decoder.buffer[offset : offset+readAmount])
   227  	decoder.cursor += readAmount
   228  	return nil
   229  }
   230  
   231  // DecodeInt64 translates data from the decoder buffer, starting from the decoder cursor, to int64.
   232  func (decoder *Decoder) DecodeInt64(msg *int64) error {
   233  	readAmount := 8
   234  	offset := decoder.cursor
   235  	if len(decoder.buffer[offset:]) < readAmount {
   236  		return ErrBufferTooShort
   237  	}
   238  	*msg = int64(binary.LittleEndian.Uint64(decoder.buffer[decoder.cursor : decoder.cursor+readAmount]))
   239  	decoder.cursor += readAmount
   240  	return nil
   241  }
   242  
   243  // DecodeBool translates data from the decoder buffer, starting from the decoder cursor, to bool.
   244  func (decoder *Decoder) DecodeBool(msg *bool) error {
   245  	offset := decoder.cursor
   246  	if len(decoder.buffer[offset:]) < 1 {
   247  		return ErrBufferTooShort
   248  	}
   249  	*msg = (decoder.buffer[offset] != 0)
   250  	decoder.cursor++
   251  	return nil
   252  }
   253  
   254  // DecodeBytes copies from the decoder buffer, starting from the decoder cursor, to msg, size bytes.
   255  func (decoder *Decoder) DecodeBytes(msg []byte, size int) error {
   256  	offset := decoder.cursor
   257  	bufferLen := len(decoder.buffer[offset:])
   258  	if bufferLen < size {
   259  		return ErrBufferTooShort
   260  	}
   261  	_ = copy(msg[:], decoder.buffer[offset:offset+size])
   262  	decoder.cursor += size
   263  	return nil
   264  }
   265  
   266  // DecodeBytesNoCopy gets bytes from current offset to given size.
   267  func (decoder *Decoder) DecodeBytesNoCopy(size int) ([]byte, error) {
   268  	offset := decoder.cursor
   269  	bufferLen := len(decoder.buffer[offset:])
   270  	if bufferLen < size {
   271  		return nil, ErrBufferTooShort
   272  	}
   273  	res := decoder.buffer[offset : offset+size]
   274  	decoder.cursor += size
   275  	return res, nil
   276  }
   277  
   278  // DecodeIntArray translate from the decoder buffer, starting from the decoder cursor, to msg, size * 4 bytes (in order to get int32).
   279  func (decoder *Decoder) DecodeIntArray(msg []int32, size int) error {
   280  	offset := decoder.cursor
   281  	if len(decoder.buffer[offset:]) < size*4 {
   282  		return ErrBufferTooShort
   283  	}
   284  	for i := 0; i < size; i++ {
   285  		msg[i] = int32(binary.LittleEndian.Uint32(decoder.buffer[decoder.cursor : decoder.cursor+4]))
   286  		decoder.cursor += 4
   287  	}
   288  	return nil
   289  }
   290  
   291  // DecodeUint64Array translate from the decoder buffer, starting from the decoder cursor, to msg, size * 8 bytes (in order to get int64).
   292  func (decoder *Decoder) DecodeUint64Array(msg *[]uint64) error {
   293  	var arrLen uint16
   294  	err := decoder.DecodeUint16(&arrLen)
   295  	if err != nil {
   296  		return fmt.Errorf("error reading ulong array number of elements: %w", err)
   297  	}
   298  	for i := 0; i < int(arrLen); i++ {
   299  		var element uint64
   300  		err := decoder.DecodeUint64(&element)
   301  		if err != nil {
   302  			return fmt.Errorf("can't read element %d uint64 from buffer: %w", i, err)
   303  		}
   304  		*msg = append(*msg, element)
   305  	}
   306  	return nil
   307  }
   308  
   309  // DecodeSlimCred translates data from the decoder buffer, starting from the decoder cursor, to SlimCred struct.
   310  func (decoder *Decoder) DecodeSlimCred(slimCred *types.SlimCred) error {
   311  	offset := decoder.cursor
   312  	if len(decoder.buffer[offset:]) < 80 {
   313  		return ErrBufferTooShort
   314  	}
   315  	slimCred.Uid = binary.LittleEndian.Uint32(decoder.buffer[offset : offset+4])
   316  	slimCred.Gid = binary.LittleEndian.Uint32(decoder.buffer[offset+4 : offset+8])
   317  	slimCred.Suid = binary.LittleEndian.Uint32(decoder.buffer[offset+8 : offset+12])
   318  	slimCred.Sgid = binary.LittleEndian.Uint32(decoder.buffer[offset+12 : offset+16])
   319  	slimCred.Euid = binary.LittleEndian.Uint32(decoder.buffer[offset+16 : offset+20])
   320  	slimCred.Egid = binary.LittleEndian.Uint32(decoder.buffer[offset+20 : offset+24])
   321  	slimCred.Fsuid = binary.LittleEndian.Uint32(decoder.buffer[offset+24 : offset+28])
   322  	slimCred.Fsgid = binary.LittleEndian.Uint32(decoder.buffer[offset+28 : offset+32])
   323  	slimCred.UserNamespace = binary.LittleEndian.Uint32(decoder.buffer[offset+32 : offset+36])
   324  	slimCred.SecureBits = binary.LittleEndian.Uint32(decoder.buffer[offset+36 : offset+40])
   325  	slimCred.CapInheritable = binary.LittleEndian.Uint64(decoder.buffer[offset+40 : offset+48])
   326  	slimCred.CapPermitted = binary.LittleEndian.Uint64(decoder.buffer[offset+48 : offset+56])
   327  	slimCred.CapEffective = binary.LittleEndian.Uint64(decoder.buffer[offset+56 : offset+64])
   328  	slimCred.CapBounding = binary.LittleEndian.Uint64(decoder.buffer[offset+64 : offset+72])
   329  	slimCred.CapAmbient = binary.LittleEndian.Uint64(decoder.buffer[offset+72 : offset+80])
   330  	decoder.cursor += int(slimCred.GetSizeBytes())
   331  	return nil
   332  }
   333  
   334  // DecodeChunkMeta translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.ChunkMeta struct.
   335  func (decoder *Decoder) DecodeChunkMeta(chunkMeta *types.ChunkMeta) error {
   336  	offset := decoder.cursor
   337  	if len(decoder.buffer[offset:]) < int(chunkMeta.GetSizeBytes()) {
   338  		return ErrBufferTooShort
   339  	}
   340  	chunkMeta.BinType = types.BinType(decoder.buffer[offset])
   341  	chunkMeta.CgroupID = binary.LittleEndian.Uint64(decoder.buffer[offset+1 : offset+9])
   342  	_ = copy(chunkMeta.Metadata[:], decoder.buffer[offset+9:offset+37])
   343  	chunkMeta.Size = int32(binary.LittleEndian.Uint32(decoder.buffer[offset+37 : offset+41]))
   344  	chunkMeta.Off = binary.LittleEndian.Uint64(decoder.buffer[offset+41 : offset+49])
   345  	decoder.cursor += int(chunkMeta.GetSizeBytes())
   346  	return nil
   347  }
   348  
   349  // DecodeVfsFileMeta translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.VfsFileMeta struct.
   350  func (decoder *Decoder) DecodeVfsFileMeta(vfsFileMeta *types.VfsFileMeta) error {
   351  	offset := decoder.cursor
   352  	if len(decoder.buffer[offset:]) < int(vfsFileMeta.GetSizeBytes()) {
   353  		return ErrBufferTooShort
   354  	}
   355  	vfsFileMeta.DevID = binary.LittleEndian.Uint32(decoder.buffer[offset : offset+4])
   356  	vfsFileMeta.Inode = binary.LittleEndian.Uint64(decoder.buffer[offset+4 : offset+12])
   357  	vfsFileMeta.Mode = binary.LittleEndian.Uint32(decoder.buffer[offset+12 : offset+16])
   358  	vfsFileMeta.Pid = binary.LittleEndian.Uint32(decoder.buffer[offset+16 : offset+20])
   359  	decoder.cursor += int(vfsFileMeta.GetSizeBytes())
   360  	return nil
   361  }
   362  
   363  // DecodeKernelModuleMeta translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.KernelModuleMeta struct.
   364  func (decoder *Decoder) DecodeKernelModuleMeta(kernelModuleMeta *types.KernelModuleMeta) error {
   365  	offset := decoder.cursor
   366  	if len(decoder.buffer[offset:]) < int(kernelModuleMeta.GetSizeBytes()) {
   367  		return ErrBufferTooShort
   368  	}
   369  	kernelModuleMeta.DevID = binary.LittleEndian.Uint32(decoder.buffer[offset : offset+4])
   370  	kernelModuleMeta.Inode = binary.LittleEndian.Uint64(decoder.buffer[offset+4 : offset+12])
   371  	kernelModuleMeta.Pid = binary.LittleEndian.Uint32(decoder.buffer[offset+12 : offset+16])
   372  	kernelModuleMeta.Size = binary.LittleEndian.Uint32(decoder.buffer[offset+16 : offset+20])
   373  	decoder.cursor += int(kernelModuleMeta.GetSizeBytes())
   374  	return nil
   375  }
   376  
   377  // DecodeBpfObjectMeta translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.BpfObjectMeta struct.
   378  func (decoder *Decoder) DecodeBpfObjectMeta(bpfObjectMeta *types.BpfObjectMeta) error {
   379  	offset := decoder.cursor
   380  	if len(decoder.buffer[offset:]) < int(bpfObjectMeta.GetSizeBytes()) {
   381  		return ErrBufferTooShort
   382  	}
   383  	_ = copy(bpfObjectMeta.Name[:], decoder.buffer[offset:offset+16])
   384  	bpfObjectMeta.Rand = binary.LittleEndian.Uint32(decoder.buffer[offset+16 : offset+20])
   385  	bpfObjectMeta.Pid = binary.LittleEndian.Uint32(decoder.buffer[offset+20 : offset+24])
   386  	bpfObjectMeta.Size = binary.LittleEndian.Uint32(decoder.buffer[offset+24 : offset+28])
   387  	decoder.cursor += int(bpfObjectMeta.GetSizeBytes())
   388  	return nil
   389  }
   390  
   391  // DecodeMprotectWriteMeta translates data from the decoder buffer, starting from the decoder cursor, to bufferdecoder.MprotectWriteMeta struct.
   392  func (decoder *Decoder) DecodeMprotectWriteMeta(mprotectWriteMeta *types.MprotectWriteMeta) error {
   393  	offset := decoder.cursor
   394  	if len(decoder.buffer[offset:]) < int(mprotectWriteMeta.GetSizeBytes()) {
   395  		return ErrBufferTooShort
   396  	}
   397  	mprotectWriteMeta.Ts = binary.LittleEndian.Uint64(decoder.buffer[offset : offset+8])
   398  	mprotectWriteMeta.Pid = binary.LittleEndian.Uint32(decoder.buffer[offset+8 : offset+12])
   399  
   400  	decoder.cursor += int(mprotectWriteMeta.GetSizeBytes())
   401  	return nil
   402  }
   403  
   404  func (decoder *Decoder) ReadSockaddrFromBuff() (types.Sockaddr, error) {
   405  	var familyInt int16
   406  	err := decoder.DecodeInt16(&familyInt)
   407  	if err != nil {
   408  		return nil, err
   409  	}
   410  	family := types.SockAddrFamily(familyInt)
   411  	switch family {
   412  	case types.AF_UNIX:
   413  		/*
   414  			http://man7.org/linux/man-pages/man7/unix.7.html
   415  			struct sockaddr_un {
   416  					sa_family_t sun_family;     // AF_UNIX
   417  					char        sun_path[108];  // Pathname
   418  			};
   419  		*/
   420  		sunPath, err := decoder.ReadStringVarFromBuff(108)
   421  		if err != nil {
   422  			return nil, fmt.Errorf("error parsing sockaddr_un: %w", err)
   423  		}
   424  		return types.UnixSockAddr{
   425  			Path: sunPath,
   426  		}, nil
   427  	case types.AF_INET:
   428  		/*
   429  			http://man7.org/linux/man-pages/man7/ip.7.html
   430  			struct sockaddr_in {
   431  				sa_family_t    sin_family; // address family: AF_INET
   432  				in_port_t      sin_port;   // port in network byte order
   433  				struct in_addr sin_addr;   // internet address
   434  				// byte        padding[8];// https://elixir.bootlin.com/linux/v4.20.17/source/include/uapi/linux/in.h#L232
   435  			};
   436  			struct in_addr {
   437  				uint32_t       s_addr;     // address in network byte order
   438  			};
   439  		*/
   440  		var port uint16
   441  		err = decoder.DecodeUint16BigEndian(&port)
   442  		if err != nil {
   443  			return nil, fmt.Errorf("error parsing sockaddr_in: %w", err)
   444  		}
   445  		addr, err := decoder.ReadByteSliceFromBuff(4)
   446  		if err != nil {
   447  			return nil, fmt.Errorf("error parsing sockaddr_in: %w", err)
   448  		}
   449  		_, err = decoder.ReadByteSliceFromBuff(8) // discard padding
   450  		if err != nil {
   451  			return nil, fmt.Errorf("error parsing sockaddr_in: %w", err)
   452  		}
   453  		return types.Ip4SockAddr{
   454  			Addr: netip.AddrPortFrom(netip.AddrFrom4([4]byte(addr)), port),
   455  		}, nil
   456  	case types.AF_INET6:
   457  		/*
   458  			struct sockaddr_in6 {
   459  				sa_family_t     sin6_family;   // AF_INET6
   460  				in_port_t       sin6_port;     // port number
   461  				uint32_t        sin6_flowinfo; // IPv6 flow information
   462  				struct in6_addr sin6_addr;     // IPv6 address
   463  				uint32_t        sin6_scope_id; // Scope ID (new in 2.4)
   464  			};
   465  
   466  			struct in6_addr {
   467  				unsigned char   s6_addr[16];   // IPv6 address
   468  			};
   469  		*/
   470  		var port uint16
   471  		err = decoder.DecodeUint16BigEndian(&port)
   472  		if err != nil {
   473  			return nil, fmt.Errorf("error parsing sockaddr_in6: %w", err)
   474  		}
   475  
   476  		var flowinfo uint32
   477  		err = decoder.DecodeUint32BigEndian(&flowinfo)
   478  		if err != nil {
   479  			return nil, fmt.Errorf("error parsing sockaddr_in6: %w", err)
   480  		}
   481  		addr, err := decoder.ReadByteSliceFromBuff(16)
   482  		if err != nil {
   483  			return nil, fmt.Errorf("error parsing sockaddr_in6: %w", err)
   484  		}
   485  		var scopeid uint32
   486  		err = decoder.DecodeUint32BigEndian(&scopeid)
   487  		if err != nil {
   488  			return nil, fmt.Errorf("error parsing sockaddr_in6: %w", err)
   489  		}
   490  
   491  		return types.Ip6SockAddr{
   492  			Addr:     netip.AddrPortFrom(netip.AddrFrom16([16]byte(addr)), port),
   493  			FlowInfo: flowinfo,
   494  			ScopeID:  scopeid,
   495  		}, nil
   496  	}
   497  
   498  	return types.NewGenericSockAddr(family), nil
   499  }
   500  
   501  func (decoder *Decoder) ReadStringFromBuff() (string, error) {
   502  	var err error
   503  	var size uint32
   504  	err = decoder.DecodeUint32(&size)
   505  	if err != nil {
   506  		return "", fmt.Errorf("error reading string size: %w", err)
   507  	}
   508  	if size > 4096 {
   509  		return "", fmt.Errorf("string size too big: %d", size)
   510  	}
   511  	res, err := decoder.ReadByteSliceFromBuff(int(size - 1)) // last byte is string terminating null
   512  	defer func() {
   513  		var dummy int8
   514  		err := decoder.DecodeInt8(&dummy) // discard last byte which is string terminating null
   515  		if err != nil {
   516  			decoder.log.Warnf("trying to discard last byte: %v", err)
   517  		}
   518  	}()
   519  	if err != nil {
   520  		return "", fmt.Errorf("error reading string arg: %w", err)
   521  	}
   522  	return string(res), nil
   523  }
   524  
   525  // readStringVarFromBuff reads a null-terminated string from `buff`
   526  // max length can be passed as `max` to optimize memory allocation, otherwise pass 0
   527  func (decoder *Decoder) ReadStringVarFromBuff(max int) (string, error) {
   528  	var err error
   529  	var char int8
   530  	res := make([]byte, 0, max)
   531  	err = decoder.DecodeInt8(&char)
   532  	if err != nil {
   533  		return "", fmt.Errorf("error reading null terminated string: %w", err)
   534  	}
   535  	var count int
   536  	for count = 1; char != 0 && count < max; count++ {
   537  		res = append(res, byte(char))
   538  		err = decoder.DecodeInt8(&char)
   539  		if err != nil {
   540  			return "", fmt.Errorf("error reading null terminated string: %w", err)
   541  		}
   542  	}
   543  	res = bytes.TrimLeft(res[:], "\000")
   544  	decoder.SeekForward(max - count)
   545  	return string(res), nil
   546  }
   547  
   548  func (decoder *Decoder) ReadByteSliceFromBuff(len int) ([]byte, error) {
   549  	res, err := decoder.DecodeBytesNoCopy(len)
   550  	if err != nil {
   551  		return nil, fmt.Errorf("error reading byte array: %w", err)
   552  	}
   553  	return res, nil
   554  }
   555  
   556  func (decoder *Decoder) ReadMaxByteSliceFromBuff(max int) ([]byte, error) {
   557  	var size uint32
   558  	err := decoder.DecodeUint32(&size)
   559  	if err != nil {
   560  		return nil, fmt.Errorf("error reading byte array size: %w", err)
   561  	}
   562  
   563  	if max >= 0 && int(size) > max {
   564  		return nil, fmt.Errorf("byte array size too big: %d", size)
   565  	}
   566  
   567  	res, err := decoder.DecodeBytesNoCopy(int(size))
   568  	if err != nil {
   569  		return nil, fmt.Errorf("error reading byte array: %w", err)
   570  	}
   571  	return res, nil
   572  }
   573  
   574  func (decoder *Decoder) ReadStringArrayFromBuff() ([]string, error) {
   575  	// TODO optimization: create slice after getting arrLen
   576  	var arrLen uint8
   577  	err := decoder.DecodeUint8(&arrLen)
   578  	if err != nil {
   579  		return nil, fmt.Errorf("error reading string array number of elements: %w", err)
   580  	}
   581  
   582  	ss := make([]string, arrLen)
   583  	for i := 0; i < int(arrLen); i++ {
   584  		s, err := decoder.ReadStringFromBuff()
   585  		if err != nil {
   586  			return nil, fmt.Errorf("error reading string element: %w", err)
   587  		}
   588  		ss[i] = s
   589  	}
   590  
   591  	return ss, nil
   592  }
   593  
   594  func (decoder *Decoder) ReadArgsArrayFromBuff() ([]string, error) {
   595  	var ss []string
   596  	var arrLen uint32
   597  	var argNum uint32
   598  
   599  	err := decoder.DecodeUint32(&arrLen)
   600  	if err != nil {
   601  		return nil, fmt.Errorf("error reading args array length: %w", err)
   602  	}
   603  	err = decoder.DecodeUint32(&argNum)
   604  	if err != nil {
   605  		return nil, fmt.Errorf("error reading args number: %w", err)
   606  	}
   607  	resBytes, err := decoder.ReadByteSliceFromBuff(int(arrLen))
   608  	if err != nil {
   609  		return nil, fmt.Errorf("error reading args array: %w", err)
   610  	}
   611  	ss = strings.Split(string(resBytes), "\x00")
   612  	if ss[len(ss)-1] == "" {
   613  		ss = ss[:len(ss)-1]
   614  	}
   615  	for int(argNum) > len(ss) {
   616  		ss = append(ss, "?")
   617  	}
   618  
   619  	return ss, nil
   620  }
   621  
   622  func (decoder *Decoder) ReadTimespec() (float64, error) {
   623  	var sec int64
   624  	var nsec int64
   625  	err := decoder.DecodeInt64(&sec)
   626  	if err != nil {
   627  		return 0, err
   628  	}
   629  	err = decoder.DecodeInt64(&nsec)
   630  	if err != nil {
   631  		return 0, err
   632  	}
   633  	return float64(sec) + (float64(nsec) / float64(1000000000)), nil
   634  }
   635  
   636  func (decoder *Decoder) ReadAddrTuple() (types.AddrTuple, error) {
   637  	srcAddr := [16]byte{}
   638  	if err := decoder.DecodeBytes(srcAddr[:], len(srcAddr)); err != nil {
   639  		return types.AddrTuple{}, err
   640  	}
   641  	dstAddr := [16]byte{}
   642  	if err := decoder.DecodeBytes(dstAddr[:], len(dstAddr)); err != nil {
   643  		return types.AddrTuple{}, err
   644  	}
   645  	var srcPort uint16
   646  	if err := decoder.DecodeUint16(&srcPort); err != nil {
   647  		return types.AddrTuple{}, err
   648  	}
   649  	var dstPort uint16
   650  	if err := decoder.DecodeUint16(&dstPort); err != nil {
   651  		return types.AddrTuple{}, err
   652  	}
   653  	var family uint16
   654  	if err := decoder.DecodeUint16(&family); err != nil {
   655  		return types.AddrTuple{}, err
   656  	}
   657  	return types.AddrTuple{
   658  		Src: addrPort(family, srcAddr, srcPort),
   659  		Dst: addrPort(family, dstAddr, dstPort),
   660  	}, nil
   661  }
   662  
   663  var errDNSMessageNotComplete = errors.New("received dns packet not complete")
   664  
   665  var dnsPacketParser = &layers.DNS{}
   666  
   667  func (decoder *Decoder) ReadProtoDNS() (*types.ProtoDNS, error) {
   668  	data, err := decoder.ReadMaxByteSliceFromBuff(eventMaxByteSliceBufferSize(events.NetPacketDNSBase))
   669  	if err != nil {
   670  		return nil, err
   671  	}
   672  
   673  	payload, subProtocol, err := packet.ExtractPayload(data)
   674  	if err != nil {
   675  		return nil, err
   676  	}
   677  
   678  	if subProtocol == packet.SubProtocolTCP {
   679  		if len(payload) < 2 {
   680  			return nil, errDNSMessageNotComplete
   681  		}
   682  
   683  		// DNS over TCP prefixes the DNS message with a two octet length field. If the payload is not as big as this specified length,
   684  		// then we cannot parse the packet, as part of the DNS message will be send in a later one.
   685  		// For more information see https://datatracker.ietf.org/doc/html/rfc1035.html#section-4.2.2
   686  		length := int(binary.BigEndian.Uint16(payload[:2]))
   687  		if len(payload)+2 < length {
   688  			return nil, errDNSMessageNotComplete
   689  		}
   690  		payload = payload[2:]
   691  	}
   692  	if err := dnsPacketParser.DecodeFromBytes(payload, gopacket.NilDecodeFeedback); err != nil {
   693  		return nil, err
   694  	}
   695  
   696  	pbDNS := &castpb.DNS{
   697  		Answers: make([]*castpb.DNSAnswers, len(dnsPacketParser.Answers)),
   698  	}
   699  
   700  	for _, v := range dnsPacketParser.Questions {
   701  		pbDNS.DNSQuestionDomain = string(v.Name)
   702  		break
   703  	}
   704  
   705  	for i, v := range dnsPacketParser.Answers {
   706  		pbDNS.Answers[i] = &castpb.DNSAnswers{
   707  			Name:  string(v.Name),
   708  			Type:  uint32(v.Type),
   709  			Class: uint32(v.Class),
   710  			Ttl:   v.TTL,
   711  			Ip:    v.IP,
   712  			Cname: string(v.CNAME),
   713  		}
   714  	}
   715  
   716  	return pbDNS, nil
   717  }
   718  
   719  func addrPort(family uint16, ip [16]byte, port uint16) netip.AddrPort {
   720  	switch types.SockAddrFamily(family) {
   721  	case types.AF_INET:
   722  		return netip.AddrPortFrom(netip.AddrFrom4([4]byte{ip[0], ip[1], ip[2], ip[3]}), port)
   723  	}
   724  	return netip.AddrPortFrom(netip.AddrFrom16(ip).Unmap(), port)
   725  }
   726  
   727  // PrintUint32IP prints the IP address encoded as a uint32
   728  func PrintUint32IP(in uint32) string {
   729  	ip := make(net.IP, net.IPv4len)
   730  	binary.BigEndian.PutUint32(ip, in)
   731  	return ip.String()
   732  }
   733  
   734  // Print16BytesSliceIP prints the IP address encoded as 16 bytes long PrintBytesSliceIP
   735  // It would be more correct to accept a [16]byte instead of variable length slice, but that would cause unnecessary memory copying and type conversions
   736  func Print16BytesSliceIP(in []byte) string {
   737  	ip := net.IP(in)
   738  	return ip.String()
   739  }