github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/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  // A MPLSLabel represents a MPLS label stack entry.
     8  type MPLSLabel struct {
     9  	Label int  // label value
    10  	TC    int  // traffic class; formerly experimental use
    11  	S     bool // bottom of stack
    12  	TTL   int  // time to live
    13  }
    14  
    15  const (
    16  	classMPLSLabelStack        = 1
    17  	typeIncomingMPLSLabelStack = 1
    18  )
    19  
    20  // A MPLSLabelStack represents a MPLS label stack.
    21  type MPLSLabelStack struct {
    22  	Class  int // extension object class number
    23  	Type   int // extension object sub-type
    24  	Labels []MPLSLabel
    25  }
    26  
    27  // Len implements the Len method of Extension interface.
    28  func (ls *MPLSLabelStack) Len(proto int) int {
    29  	return 4 + (4 * len(ls.Labels))
    30  }
    31  
    32  // Marshal implements the Marshal method of Extension interface.
    33  func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {
    34  	b := make([]byte, ls.Len(proto))
    35  	if err := ls.marshal(proto, b); err != nil {
    36  		return nil, err
    37  	}
    38  	return b, nil
    39  }
    40  
    41  func (ls *MPLSLabelStack) marshal(proto int, b []byte) error {
    42  	l := ls.Len(proto)
    43  	b[0], b[1] = byte(l>>8), byte(l)
    44  	b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack
    45  	off := 4
    46  	for _, ll := range ls.Labels {
    47  		b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)
    48  		b[off+2] |= byte(ll.TC << 1 & 0x0e)
    49  		if ll.S {
    50  			b[off+2] |= 0x1
    51  		}
    52  		b[off+3] = byte(ll.TTL)
    53  		off += 4
    54  	}
    55  	return nil
    56  }
    57  
    58  func parseMPLSLabelStack(b []byte) (Extension, error) {
    59  	ls := &MPLSLabelStack{
    60  		Class: int(b[2]),
    61  		Type:  int(b[3]),
    62  	}
    63  	for b = b[4:]; len(b) >= 4; b = b[4:] {
    64  		ll := MPLSLabel{
    65  			Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,
    66  			TC:    int(b[2]&0x0e) >> 1,
    67  			TTL:   int(b[3]),
    68  		}
    69  		if b[2]&0x1 != 0 {
    70  			ll.S = true
    71  		}
    72  		ls.Labels = append(ls.Labels, ll)
    73  	}
    74  	return ls, nil
    75  }