github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/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 }