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 }