paramheader.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. var (
  17. errParamHeaderTooShort = errors.New("param header too short")
  18. errParamHeaderSelfReportedLengthShorter = errors.New("param self reported length is shorter than header length")
  19. errParamHeaderSelfReportedLengthLonger = errors.New("param self reported length is longer than header length")
  20. errParamHeaderParseFailed = errors.New("failed to parse param type")
  21. )
  22. func (p *paramHeader) marshal() ([]byte, error) {
  23. paramLengthPlusHeader := paramHeaderLength + len(p.raw)
  24. rawParam := make([]byte, paramLengthPlusHeader)
  25. binary.BigEndian.PutUint16(rawParam[0:], uint16(p.typ))
  26. binary.BigEndian.PutUint16(rawParam[2:], uint16(paramLengthPlusHeader))
  27. copy(rawParam[paramHeaderLength:], p.raw)
  28. return rawParam, nil
  29. }
  30. func (p *paramHeader) unmarshal(raw []byte) error {
  31. if len(raw) < paramHeaderLength {
  32. return errParamHeaderTooShort
  33. }
  34. paramLengthPlusHeader := binary.BigEndian.Uint16(raw[2:])
  35. if int(paramLengthPlusHeader) < paramHeaderLength {
  36. return fmt.Errorf("%w: param self reported length (%d) shorter than header length (%d)", errParamHeaderSelfReportedLengthShorter, int(paramLengthPlusHeader), paramHeaderLength)
  37. }
  38. if len(raw) < int(paramLengthPlusHeader) {
  39. return fmt.Errorf("%w: param length (%d) shorter than its self reported length (%d)", errParamHeaderSelfReportedLengthLonger, len(raw), int(paramLengthPlusHeader))
  40. }
  41. typ, err := parseParamType(raw[0:])
  42. if err != nil {
  43. return fmt.Errorf("%w: %v", errParamHeaderParseFailed, err)
  44. }
  45. p.typ = typ
  46. p.raw = raw[paramHeaderLength:paramLengthPlusHeader]
  47. p.len = int(paramLengthPlusHeader)
  48. return nil
  49. }
  50. func (p *paramHeader) length() int {
  51. return p.len
  52. }
  53. // String makes paramHeader printable
  54. func (p paramHeader) String() string {
  55. return fmt.Sprintf("%s (%d): %s", p.typ, p.len, hex.Dump(p.raw))
  56. }