github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/golang.org/x/net/icmp/mpls.go (about)

     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  // MPLSLabel represents an 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  // MPLSLabelStack represents an 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  }