mpls.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package icmp
  5. import "encoding/binary"
  6. // MPLSLabel represents an MPLS label stack entry.
  7. type MPLSLabel struct {
  8. Label int // label value
  9. TC int // traffic class; formerly experimental use
  10. S bool // bottom of stack
  11. TTL int // time to live
  12. }
  13. const (
  14. classMPLSLabelStack = 1
  15. typeIncomingMPLSLabelStack = 1
  16. )
  17. // MPLSLabelStack represents an MPLS label stack.
  18. type MPLSLabelStack struct {
  19. Class int // extension object class number
  20. Type int // extension object sub-type
  21. Labels []MPLSLabel
  22. }
  23. // Len implements the Len method of Extension interface.
  24. func (ls *MPLSLabelStack) Len(proto int) int {
  25. return 4 + (4 * len(ls.Labels))
  26. }
  27. // Marshal implements the Marshal method of Extension interface.
  28. func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {
  29. b := make([]byte, ls.Len(proto))
  30. if err := ls.marshal(proto, b); err != nil {
  31. return nil, err
  32. }
  33. return b, nil
  34. }
  35. func (ls *MPLSLabelStack) marshal(proto int, b []byte) error {
  36. l := ls.Len(proto)
  37. binary.BigEndian.PutUint16(b[:2], uint16(l))
  38. b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack
  39. off := 4
  40. for _, ll := range ls.Labels {
  41. b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)
  42. b[off+2] |= byte(ll.TC << 1 & 0x0e)
  43. if ll.S {
  44. b[off+2] |= 0x1
  45. }
  46. b[off+3] = byte(ll.TTL)
  47. off += 4
  48. }
  49. return nil
  50. }
  51. func parseMPLSLabelStack(b []byte) (Extension, error) {
  52. ls := &MPLSLabelStack{
  53. Class: int(b[2]),
  54. Type: int(b[3]),
  55. }
  56. for b = b[4:]; len(b) >= 4; b = b[4:] {
  57. ll := MPLSLabel{
  58. Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,
  59. TC: int(b[2]&0x0e) >> 1,
  60. TTL: int(b[3]),
  61. }
  62. if b[2]&0x1 != 0 {
  63. ll.S = true
  64. }
  65. ls.Labels = append(ls.Labels, ll)
  66. }
  67. return ls, nil
  68. }