sctp.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. package layers
  7. import (
  8. "encoding/binary"
  9. "errors"
  10. "fmt"
  11. "hash/crc32"
  12. "github.com/google/gopacket"
  13. )
  14. // SCTP contains information on the top level of an SCTP packet.
  15. type SCTP struct {
  16. BaseLayer
  17. SrcPort, DstPort SCTPPort
  18. VerificationTag uint32
  19. Checksum uint32
  20. sPort, dPort []byte
  21. }
  22. // LayerType returns gopacket.LayerTypeSCTP
  23. func (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP }
  24. func decodeSCTP(data []byte, p gopacket.PacketBuilder) error {
  25. sctp := &SCTP{}
  26. err := sctp.DecodeFromBytes(data, p)
  27. p.AddLayer(sctp)
  28. p.SetTransportLayer(sctp)
  29. if err != nil {
  30. return err
  31. }
  32. return p.NextDecoder(sctpChunkTypePrefixDecoder)
  33. }
  34. var sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)
  35. // TransportFlow returns a flow based on the source and destination SCTP port.
  36. func (s *SCTP) TransportFlow() gopacket.Flow {
  37. return gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort)
  38. }
  39. func decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error {
  40. chunkType := SCTPChunkType(data[0])
  41. return chunkType.Decode(data, p)
  42. }
  43. // SerializeTo is for gopacket.SerializableLayer.
  44. func (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  45. bytes, err := b.PrependBytes(12)
  46. if err != nil {
  47. return err
  48. }
  49. binary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort))
  50. binary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort))
  51. binary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag)
  52. if opts.ComputeChecksums {
  53. // Note: MakeTable(Castagnoli) actually only creates the table once, then
  54. // passes back a singleton on every other call, so this shouldn't cause
  55. // excessive memory allocation.
  56. binary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli)))
  57. }
  58. return nil
  59. }
  60. func (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  61. if len(data) < 12 {
  62. return errors.New("Invalid SCTP common header length")
  63. }
  64. sctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2]))
  65. sctp.sPort = data[:2]
  66. sctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4]))
  67. sctp.dPort = data[2:4]
  68. sctp.VerificationTag = binary.BigEndian.Uint32(data[4:8])
  69. sctp.Checksum = binary.BigEndian.Uint32(data[8:12])
  70. sctp.BaseLayer = BaseLayer{data[:12], data[12:]}
  71. return nil
  72. }
  73. func (t *SCTP) CanDecode() gopacket.LayerClass {
  74. return LayerTypeSCTP
  75. }
  76. func (t *SCTP) NextLayerType() gopacket.LayerType {
  77. return gopacket.LayerTypePayload
  78. }
  79. // SCTPChunk contains the common fields in all SCTP chunks.
  80. type SCTPChunk struct {
  81. BaseLayer
  82. Type SCTPChunkType
  83. Flags uint8
  84. Length uint16
  85. // ActualLength is the total length of an SCTP chunk, including padding.
  86. // SCTP chunks start and end on 4-byte boundaries. So if a chunk has a length
  87. // of 18, it means that it has data up to and including byte 18, then padding
  88. // up to the next 4-byte boundary, 20. In this case, Length would be 18, and
  89. // ActualLength would be 20.
  90. ActualLength int
  91. }
  92. func roundUpToNearest4(i int) int {
  93. if i%4 == 0 {
  94. return i
  95. }
  96. return i + 4 - (i % 4)
  97. }
  98. func decodeSCTPChunk(data []byte) (SCTPChunk, error) {
  99. length := binary.BigEndian.Uint16(data[2:4])
  100. if length < 4 {
  101. return SCTPChunk{}, errors.New("invalid SCTP chunk length")
  102. }
  103. actual := roundUpToNearest4(int(length))
  104. ct := SCTPChunkType(data[0])
  105. // For SCTP Data, use a separate layer for the payload
  106. delta := 0
  107. if ct == SCTPChunkTypeData {
  108. delta = int(actual) - int(length)
  109. actual = 16
  110. }
  111. return SCTPChunk{
  112. Type: ct,
  113. Flags: data[1],
  114. Length: length,
  115. ActualLength: actual,
  116. BaseLayer: BaseLayer{data[:actual], data[actual : len(data)-delta]},
  117. }, nil
  118. }
  119. // SCTPParameter is a TLV parameter inside a SCTPChunk.
  120. type SCTPParameter struct {
  121. Type uint16
  122. Length uint16
  123. ActualLength int
  124. Value []byte
  125. }
  126. func decodeSCTPParameter(data []byte) SCTPParameter {
  127. length := binary.BigEndian.Uint16(data[2:4])
  128. return SCTPParameter{
  129. Type: binary.BigEndian.Uint16(data[0:2]),
  130. Length: length,
  131. Value: data[4:length],
  132. ActualLength: roundUpToNearest4(int(length)),
  133. }
  134. }
  135. func (p SCTPParameter) Bytes() []byte {
  136. length := 4 + len(p.Value)
  137. data := make([]byte, roundUpToNearest4(length))
  138. binary.BigEndian.PutUint16(data[0:2], p.Type)
  139. binary.BigEndian.PutUint16(data[2:4], uint16(length))
  140. copy(data[4:], p.Value)
  141. return data
  142. }
  143. // SCTPUnknownChunkType is the layer type returned when we don't recognize the
  144. // chunk type. Since there's a length in a known location, we can skip over
  145. // it even if we don't know what it is, and continue parsing the rest of the
  146. // chunks. This chunk is stored as an ErrorLayer in the packet.
  147. type SCTPUnknownChunkType struct {
  148. SCTPChunk
  149. bytes []byte
  150. }
  151. func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error {
  152. chunk, err := decodeSCTPChunk(data)
  153. if err != nil {
  154. return err
  155. }
  156. sc := &SCTPUnknownChunkType{SCTPChunk: chunk}
  157. sc.bytes = data[:sc.ActualLength]
  158. p.AddLayer(sc)
  159. p.SetErrorLayer(sc)
  160. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  161. }
  162. // SerializeTo is for gopacket.SerializableLayer.
  163. func (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  164. bytes, err := b.PrependBytes(s.ActualLength)
  165. if err != nil {
  166. return err
  167. }
  168. copy(bytes, s.bytes)
  169. return nil
  170. }
  171. // LayerType returns gopacket.LayerTypeSCTPUnknownChunkType.
  172. func (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType }
  173. // Payload returns all bytes in this header, including the decoded Type, Length,
  174. // and Flags.
  175. func (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes }
  176. // Error implements ErrorLayer.
  177. func (s *SCTPUnknownChunkType) Error() error {
  178. return fmt.Errorf("No decode method available for SCTP chunk type %s", s.Type)
  179. }
  180. // SCTPData is the SCTP Data chunk layer.
  181. type SCTPData struct {
  182. SCTPChunk
  183. Unordered, BeginFragment, EndFragment bool
  184. TSN uint32
  185. StreamId uint16
  186. StreamSequence uint16
  187. PayloadProtocol SCTPPayloadProtocol
  188. }
  189. // LayerType returns gopacket.LayerTypeSCTPData.
  190. func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData }
  191. // SCTPPayloadProtocol represents a payload protocol
  192. type SCTPPayloadProtocol uint32
  193. // SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml
  194. const (
  195. SCTPProtocolReserved SCTPPayloadProtocol = 0
  196. SCTPPayloadUIA = 1
  197. SCTPPayloadM2UA = 2
  198. SCTPPayloadM3UA = 3
  199. SCTPPayloadSUA = 4
  200. SCTPPayloadM2PA = 5
  201. SCTPPayloadV5UA = 6
  202. SCTPPayloadH248 = 7
  203. SCTPPayloadBICC = 8
  204. SCTPPayloadTALI = 9
  205. SCTPPayloadDUA = 10
  206. SCTPPayloadASAP = 11
  207. SCTPPayloadENRP = 12
  208. SCTPPayloadH323 = 13
  209. SCTPPayloadQIPC = 14
  210. SCTPPayloadSIMCO = 15
  211. SCTPPayloadDDPSegment = 16
  212. SCTPPayloadDDPStream = 17
  213. SCTPPayloadS1AP = 18
  214. )
  215. func (p SCTPPayloadProtocol) String() string {
  216. switch p {
  217. case SCTPProtocolReserved:
  218. return "Reserved"
  219. case SCTPPayloadUIA:
  220. return "UIA"
  221. case SCTPPayloadM2UA:
  222. return "M2UA"
  223. case SCTPPayloadM3UA:
  224. return "M3UA"
  225. case SCTPPayloadSUA:
  226. return "SUA"
  227. case SCTPPayloadM2PA:
  228. return "M2PA"
  229. case SCTPPayloadV5UA:
  230. return "V5UA"
  231. case SCTPPayloadH248:
  232. return "H.248"
  233. case SCTPPayloadBICC:
  234. return "BICC"
  235. case SCTPPayloadTALI:
  236. return "TALI"
  237. case SCTPPayloadDUA:
  238. return "DUA"
  239. case SCTPPayloadASAP:
  240. return "ASAP"
  241. case SCTPPayloadENRP:
  242. return "ENRP"
  243. case SCTPPayloadH323:
  244. return "H.323"
  245. case SCTPPayloadQIPC:
  246. return "QIPC"
  247. case SCTPPayloadSIMCO:
  248. return "SIMCO"
  249. case SCTPPayloadDDPSegment:
  250. return "DDPSegment"
  251. case SCTPPayloadDDPStream:
  252. return "DDPStream"
  253. case SCTPPayloadS1AP:
  254. return "S1AP"
  255. }
  256. return fmt.Sprintf("Unknown(%d)", p)
  257. }
  258. func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error {
  259. chunk, err := decodeSCTPChunk(data)
  260. if err != nil {
  261. return err
  262. }
  263. sc := &SCTPData{
  264. SCTPChunk: chunk,
  265. Unordered: data[1]&0x4 != 0,
  266. BeginFragment: data[1]&0x2 != 0,
  267. EndFragment: data[1]&0x1 != 0,
  268. TSN: binary.BigEndian.Uint32(data[4:8]),
  269. StreamId: binary.BigEndian.Uint16(data[8:10]),
  270. StreamSequence: binary.BigEndian.Uint16(data[10:12]),
  271. PayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])),
  272. }
  273. // Length is the length in bytes of the data, INCLUDING the 16-byte header.
  274. p.AddLayer(sc)
  275. return p.NextDecoder(gopacket.LayerTypePayload)
  276. }
  277. // SerializeTo is for gopacket.SerializableLayer.
  278. func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  279. payload := b.Bytes()
  280. // Pad the payload to a 32 bit boundary
  281. if rem := len(payload) % 4; rem != 0 {
  282. b.AppendBytes(4 - rem)
  283. }
  284. length := 16
  285. bytes, err := b.PrependBytes(length)
  286. if err != nil {
  287. return err
  288. }
  289. bytes[0] = uint8(sc.Type)
  290. flags := uint8(0)
  291. if sc.Unordered {
  292. flags |= 0x4
  293. }
  294. if sc.BeginFragment {
  295. flags |= 0x2
  296. }
  297. if sc.EndFragment {
  298. flags |= 0x1
  299. }
  300. bytes[1] = flags
  301. binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload)))
  302. binary.BigEndian.PutUint32(bytes[4:8], sc.TSN)
  303. binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId)
  304. binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence)
  305. binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol))
  306. return nil
  307. }
  308. // SCTPInitParameter is a parameter for an SCTP Init or InitAck packet.
  309. type SCTPInitParameter SCTPParameter
  310. // SCTPInit is used as the return value for both SCTPInit and SCTPInitAck
  311. // messages.
  312. type SCTPInit struct {
  313. SCTPChunk
  314. InitiateTag uint32
  315. AdvertisedReceiverWindowCredit uint32
  316. OutboundStreams, InboundStreams uint16
  317. InitialTSN uint32
  318. Parameters []SCTPInitParameter
  319. }
  320. // LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck.
  321. func (sc *SCTPInit) LayerType() gopacket.LayerType {
  322. if sc.Type == SCTPChunkTypeInitAck {
  323. return LayerTypeSCTPInitAck
  324. }
  325. // sc.Type == SCTPChunkTypeInit
  326. return LayerTypeSCTPInit
  327. }
  328. func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error {
  329. chunk, err := decodeSCTPChunk(data)
  330. if err != nil {
  331. return err
  332. }
  333. sc := &SCTPInit{
  334. SCTPChunk: chunk,
  335. InitiateTag: binary.BigEndian.Uint32(data[4:8]),
  336. AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
  337. OutboundStreams: binary.BigEndian.Uint16(data[12:14]),
  338. InboundStreams: binary.BigEndian.Uint16(data[14:16]),
  339. InitialTSN: binary.BigEndian.Uint32(data[16:20]),
  340. }
  341. paramData := data[20:sc.ActualLength]
  342. for len(paramData) > 0 {
  343. p := SCTPInitParameter(decodeSCTPParameter(paramData))
  344. paramData = paramData[p.ActualLength:]
  345. sc.Parameters = append(sc.Parameters, p)
  346. }
  347. p.AddLayer(sc)
  348. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  349. }
  350. // SerializeTo is for gopacket.SerializableLayer.
  351. func (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  352. var payload []byte
  353. for _, param := range sc.Parameters {
  354. payload = append(payload, SCTPParameter(param).Bytes()...)
  355. }
  356. length := 20 + len(payload)
  357. bytes, err := b.PrependBytes(roundUpToNearest4(length))
  358. if err != nil {
  359. return err
  360. }
  361. bytes[0] = uint8(sc.Type)
  362. bytes[1] = sc.Flags
  363. binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
  364. binary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag)
  365. binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
  366. binary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams)
  367. binary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams)
  368. binary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN)
  369. copy(bytes[20:], payload)
  370. return nil
  371. }
  372. // SCTPSack is the SCTP Selective ACK chunk layer.
  373. type SCTPSack struct {
  374. SCTPChunk
  375. CumulativeTSNAck uint32
  376. AdvertisedReceiverWindowCredit uint32
  377. NumGapACKs, NumDuplicateTSNs uint16
  378. GapACKs []uint16
  379. DuplicateTSNs []uint32
  380. }
  381. // LayerType return LayerTypeSCTPSack
  382. func (sc *SCTPSack) LayerType() gopacket.LayerType {
  383. return LayerTypeSCTPSack
  384. }
  385. func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error {
  386. chunk, err := decodeSCTPChunk(data)
  387. if err != nil {
  388. return err
  389. }
  390. sc := &SCTPSack{
  391. SCTPChunk: chunk,
  392. CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
  393. AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
  394. NumGapACKs: binary.BigEndian.Uint16(data[12:14]),
  395. NumDuplicateTSNs: binary.BigEndian.Uint16(data[14:16]),
  396. }
  397. // We maximize gapAcks and dupTSNs here so we're not allocating tons
  398. // of memory based on a user-controlable field. Our maximums are not exact,
  399. // but should give us sane defaults... we'll still hit slice boundaries and
  400. // fail if the user-supplied values are too high (in the for loops below), but
  401. // the amount of memory we'll have allocated because of that should be small
  402. // (< sc.ActualLength)
  403. gapAcks := sc.SCTPChunk.ActualLength / 2
  404. dupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4
  405. if gapAcks > int(sc.NumGapACKs) {
  406. gapAcks = int(sc.NumGapACKs)
  407. }
  408. if dupTSNs > int(sc.NumDuplicateTSNs) {
  409. dupTSNs = int(sc.NumDuplicateTSNs)
  410. }
  411. sc.GapACKs = make([]uint16, 0, gapAcks)
  412. sc.DuplicateTSNs = make([]uint32, 0, dupTSNs)
  413. bytesRemaining := data[16:]
  414. for i := 0; i < int(sc.NumGapACKs); i++ {
  415. sc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2]))
  416. bytesRemaining = bytesRemaining[2:]
  417. }
  418. for i := 0; i < int(sc.NumDuplicateTSNs); i++ {
  419. sc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4]))
  420. bytesRemaining = bytesRemaining[4:]
  421. }
  422. p.AddLayer(sc)
  423. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  424. }
  425. // SerializeTo is for gopacket.SerializableLayer.
  426. func (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  427. length := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs)
  428. bytes, err := b.PrependBytes(roundUpToNearest4(length))
  429. if err != nil {
  430. return err
  431. }
  432. bytes[0] = uint8(sc.Type)
  433. bytes[1] = sc.Flags
  434. binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
  435. binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
  436. binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
  437. binary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs)))
  438. binary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs)))
  439. for i, v := range sc.GapACKs {
  440. binary.BigEndian.PutUint16(bytes[16+i*2:], v)
  441. }
  442. offset := 16 + 2*len(sc.GapACKs)
  443. for i, v := range sc.DuplicateTSNs {
  444. binary.BigEndian.PutUint32(bytes[offset+i*4:], v)
  445. }
  446. return nil
  447. }
  448. // SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and
  449. // heartbeat ack layers.
  450. type SCTPHeartbeatParameter SCTPParameter
  451. // SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack.
  452. type SCTPHeartbeat struct {
  453. SCTPChunk
  454. Parameters []SCTPHeartbeatParameter
  455. }
  456. // LayerType returns gopacket.LayerTypeSCTPHeartbeat.
  457. func (sc *SCTPHeartbeat) LayerType() gopacket.LayerType {
  458. if sc.Type == SCTPChunkTypeHeartbeatAck {
  459. return LayerTypeSCTPHeartbeatAck
  460. }
  461. // sc.Type == SCTPChunkTypeHeartbeat
  462. return LayerTypeSCTPHeartbeat
  463. }
  464. func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error {
  465. chunk, err := decodeSCTPChunk(data)
  466. if err != nil {
  467. return err
  468. }
  469. sc := &SCTPHeartbeat{
  470. SCTPChunk: chunk,
  471. }
  472. paramData := data[4:sc.Length]
  473. for len(paramData) > 0 {
  474. p := SCTPHeartbeatParameter(decodeSCTPParameter(paramData))
  475. paramData = paramData[p.ActualLength:]
  476. sc.Parameters = append(sc.Parameters, p)
  477. }
  478. p.AddLayer(sc)
  479. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  480. }
  481. // SerializeTo is for gopacket.SerializableLayer.
  482. func (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  483. var payload []byte
  484. for _, param := range sc.Parameters {
  485. payload = append(payload, SCTPParameter(param).Bytes()...)
  486. }
  487. length := 4 + len(payload)
  488. bytes, err := b.PrependBytes(roundUpToNearest4(length))
  489. if err != nil {
  490. return err
  491. }
  492. bytes[0] = uint8(sc.Type)
  493. bytes[1] = sc.Flags
  494. binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
  495. copy(bytes[4:], payload)
  496. return nil
  497. }
  498. // SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers.
  499. type SCTPErrorParameter SCTPParameter
  500. // SCTPError is the SCTP error layer, also used for SCTP aborts.
  501. type SCTPError struct {
  502. SCTPChunk
  503. Parameters []SCTPErrorParameter
  504. }
  505. // LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError.
  506. func (sc *SCTPError) LayerType() gopacket.LayerType {
  507. if sc.Type == SCTPChunkTypeAbort {
  508. return LayerTypeSCTPAbort
  509. }
  510. // sc.Type == SCTPChunkTypeError
  511. return LayerTypeSCTPError
  512. }
  513. func decodeSCTPError(data []byte, p gopacket.PacketBuilder) error {
  514. // remarkably similar to decodeSCTPHeartbeat ;)
  515. chunk, err := decodeSCTPChunk(data)
  516. if err != nil {
  517. return err
  518. }
  519. sc := &SCTPError{
  520. SCTPChunk: chunk,
  521. }
  522. paramData := data[4:sc.Length]
  523. for len(paramData) > 0 {
  524. p := SCTPErrorParameter(decodeSCTPParameter(paramData))
  525. paramData = paramData[p.ActualLength:]
  526. sc.Parameters = append(sc.Parameters, p)
  527. }
  528. p.AddLayer(sc)
  529. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  530. }
  531. // SerializeTo is for gopacket.SerializableLayer.
  532. func (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  533. var payload []byte
  534. for _, param := range sc.Parameters {
  535. payload = append(payload, SCTPParameter(param).Bytes()...)
  536. }
  537. length := 4 + len(payload)
  538. bytes, err := b.PrependBytes(roundUpToNearest4(length))
  539. if err != nil {
  540. return err
  541. }
  542. bytes[0] = uint8(sc.Type)
  543. bytes[1] = sc.Flags
  544. binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
  545. copy(bytes[4:], payload)
  546. return nil
  547. }
  548. // SCTPShutdown is the SCTP shutdown layer.
  549. type SCTPShutdown struct {
  550. SCTPChunk
  551. CumulativeTSNAck uint32
  552. }
  553. // LayerType returns gopacket.LayerTypeSCTPShutdown.
  554. func (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown }
  555. func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error {
  556. chunk, err := decodeSCTPChunk(data)
  557. if err != nil {
  558. return err
  559. }
  560. sc := &SCTPShutdown{
  561. SCTPChunk: chunk,
  562. CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
  563. }
  564. p.AddLayer(sc)
  565. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  566. }
  567. // SerializeTo is for gopacket.SerializableLayer.
  568. func (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  569. bytes, err := b.PrependBytes(8)
  570. if err != nil {
  571. return err
  572. }
  573. bytes[0] = uint8(sc.Type)
  574. bytes[1] = sc.Flags
  575. binary.BigEndian.PutUint16(bytes[2:4], 8)
  576. binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
  577. return nil
  578. }
  579. // SCTPShutdownAck is the SCTP shutdown layer.
  580. type SCTPShutdownAck struct {
  581. SCTPChunk
  582. }
  583. // LayerType returns gopacket.LayerTypeSCTPShutdownAck.
  584. func (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck }
  585. func decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error {
  586. chunk, err := decodeSCTPChunk(data)
  587. if err != nil {
  588. return err
  589. }
  590. sc := &SCTPShutdownAck{
  591. SCTPChunk: chunk,
  592. }
  593. p.AddLayer(sc)
  594. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  595. }
  596. // SerializeTo is for gopacket.SerializableLayer.
  597. func (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  598. bytes, err := b.PrependBytes(4)
  599. if err != nil {
  600. return err
  601. }
  602. bytes[0] = uint8(sc.Type)
  603. bytes[1] = sc.Flags
  604. binary.BigEndian.PutUint16(bytes[2:4], 4)
  605. return nil
  606. }
  607. // SCTPCookieEcho is the SCTP Cookie Echo layer.
  608. type SCTPCookieEcho struct {
  609. SCTPChunk
  610. Cookie []byte
  611. }
  612. // LayerType returns gopacket.LayerTypeSCTPCookieEcho.
  613. func (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho }
  614. func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error {
  615. chunk, err := decodeSCTPChunk(data)
  616. if err != nil {
  617. return err
  618. }
  619. sc := &SCTPCookieEcho{
  620. SCTPChunk: chunk,
  621. }
  622. sc.Cookie = data[4:sc.Length]
  623. p.AddLayer(sc)
  624. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  625. }
  626. // SerializeTo is for gopacket.SerializableLayer.
  627. func (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  628. length := 4 + len(sc.Cookie)
  629. bytes, err := b.PrependBytes(roundUpToNearest4(length))
  630. if err != nil {
  631. return err
  632. }
  633. bytes[0] = uint8(sc.Type)
  634. bytes[1] = sc.Flags
  635. binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
  636. copy(bytes[4:], sc.Cookie)
  637. return nil
  638. }
  639. // This struct is used by all empty SCTP chunks (currently CookieAck and
  640. // ShutdownComplete).
  641. type SCTPEmptyLayer struct {
  642. SCTPChunk
  643. }
  644. // LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or
  645. // LayerTypeSCTPCookieAck.
  646. func (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType {
  647. if sc.Type == SCTPChunkTypeShutdownComplete {
  648. return LayerTypeSCTPShutdownComplete
  649. }
  650. // sc.Type == SCTPChunkTypeCookieAck
  651. return LayerTypeSCTPCookieAck
  652. }
  653. func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error {
  654. chunk, err := decodeSCTPChunk(data)
  655. if err != nil {
  656. return err
  657. }
  658. sc := &SCTPEmptyLayer{
  659. SCTPChunk: chunk,
  660. }
  661. p.AddLayer(sc)
  662. return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
  663. }
  664. // SerializeTo is for gopacket.SerializableLayer.
  665. func (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  666. bytes, err := b.PrependBytes(4)
  667. if err != nil {
  668. return err
  669. }
  670. bytes[0] = uint8(sc.Type)
  671. bytes[1] = sc.Flags
  672. binary.BigEndian.PutUint16(bytes[2:4], 4)
  673. return nil
  674. }