OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / icmp / mpls.go
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
5 package icmp
6
7 import "encoding/binary"
8
9 // A MPLSLabel represents a MPLS label stack entry.
10 type MPLSLabel struct {
11         Label int  // label value
12         TC    int  // traffic class; formerly experimental use
13         S     bool // bottom of stack
14         TTL   int  // time to live
15 }
16
17 const (
18         classMPLSLabelStack        = 1
19         typeIncomingMPLSLabelStack = 1
20 )
21
22 // A MPLSLabelStack represents a MPLS label stack.
23 type MPLSLabelStack struct {
24         Class  int // extension object class number
25         Type   int // extension object sub-type
26         Labels []MPLSLabel
27 }
28
29 // Len implements the Len method of Extension interface.
30 func (ls *MPLSLabelStack) Len(proto int) int {
31         return 4 + (4 * len(ls.Labels))
32 }
33
34 // Marshal implements the Marshal method of Extension interface.
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 }