paramheader.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package sctp
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "errors"
  6. "fmt"
  7. )
  8. type paramHeader struct {
  9. typ paramType
  10. len int
  11. raw []byte
  12. }
  13. const (
  14. paramHeaderLength = 4
  15. )
  16. // Parameter header parse errors
  17. var (
  18. ErrParamHeaderTooShort = errors.New("param header too short")
  19. ErrParamHeaderSelfReportedLengthShorter = errors.New("param self reported length is shorter than header length")
  20. ErrParamHeaderSelfReportedLengthLonger = errors.New("param self reported length is longer than header length")
  21. ErrParamHeaderParseFailed = errors.New("failed to parse param type")
  22. )
  23. func (p *paramHeader) marshal() ([]byte, error) {
  24. paramLengthPlusHeader := paramHeaderLength + len(p.raw)
  25. rawParam := make([]byte, paramLengthPlusHeader)
  26. binary.BigEndian.PutUint16(rawParam[0:], uint16(p.typ))
  27. binary.BigEndian.PutUint16(rawParam[2:], uint16(paramLengthPlusHeader))
  28. copy(rawParam[paramHeaderLength:], p.raw)
  29. return rawParam, nil
  30. }
  31. func (p *paramHeader) unmarshal(raw []byte) error {
  32. if len(raw) < paramHeaderLength {
  33. return ErrParamHeaderTooShort
  34. }
  35. paramLengthPlusHeader := binary.BigEndian.Uint16(raw[2:])
  36. if int(paramLengthPlusHeader) < paramHeaderLength {
  37. return fmt.Errorf("%w: param self reported length (%d) shorter than header length (%d)", ErrParamHeaderSelfReportedLengthShorter, int(paramLengthPlusHeader), paramHeaderLength)
  38. }
  39. if len(raw) < int(paramLengthPlusHeader) {
  40. return fmt.Errorf("%w: param length (%d) shorter than its self reported length (%d)", ErrParamHeaderSelfReportedLengthLonger, len(raw), int(paramLengthPlusHeader))
  41. }
  42. typ, err := parseParamType(raw[0:])
  43. if err != nil {
  44. return fmt.Errorf("%w: %v", ErrParamHeaderParseFailed, err) //nolint:errorlint
  45. }
  46. p.typ = typ
  47. p.raw = raw[paramHeaderLength:paramLengthPlusHeader]
  48. p.len = int(paramLengthPlusHeader)
  49. return nil
  50. }
  51. func (p *paramHeader) length() int {
  52. return p.len
  53. }
  54. // String makes paramHeader printable
  55. func (p paramHeader) String() string {
  56. return fmt.Sprintf("%s (%d): %s", p.typ, p.len, hex.Dump(p.raw))
  57. }