...
1
2
3
4
5 package icmp
6
7 import "encoding/binary"
8
9
10 type MPLSLabel struct {
11 Label int
12 TC int
13 S bool
14 TTL int
15 }
16
17 const (
18 classMPLSLabelStack = 1
19 typeIncomingMPLSLabelStack = 1
20 )
21
22
23 type MPLSLabelStack struct {
24 Class int
25 Type int
26 Labels []MPLSLabel
27 }
28
29
30 func (ls *MPLSLabelStack) Len(proto int) int {
31 return 4 + (4 * len(ls.Labels))
32 }
33
34
35 func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {
36 b := make([]byte, ls.Len(proto))
37 if err := ls.marshal(proto, b); err != nil {
38 return nil, err
39 }
40 return b, nil
41 }
42
43 func (ls *MPLSLabelStack) marshal(proto int, b []byte) error {
44 l := ls.Len(proto)
45 binary.BigEndian.PutUint16(b[:2], uint16(l))
46 b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack
47 off := 4
48 for _, ll := range ls.Labels {
49 b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)
50 b[off+2] |= byte(ll.TC << 1 & 0x0e)
51 if ll.S {
52 b[off+2] |= 0x1
53 }
54 b[off+3] = byte(ll.TTL)
55 off += 4
56 }
57 return nil
58 }
59
60 func parseMPLSLabelStack(b []byte) (Extension, error) {
61 ls := &MPLSLabelStack{
62 Class: int(b[2]),
63 Type: int(b[3]),
64 }
65 for b = b[4:]; len(b) >= 4; b = b[4:] {
66 ll := MPLSLabel{
67 Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,
68 TC: int(b[2]&0x0e) >> 1,
69 TTL: int(b[3]),
70 }
71 if b[2]&0x1 != 0 {
72 ll.S = true
73 }
74 ls.Labels = append(ls.Labels, ll)
75 }
76 return ls, nil
77 }
78
View as plain text