|
|
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package icmp
import "encoding/binary"
// A MPLSLabel represents a MPLS label stack entry.
type MPLSLabel struct { Label int // label value
TC int // traffic class; formerly experimental use
S bool // bottom of stack
TTL int // time to live
}
const ( classMPLSLabelStack = 1 typeIncomingMPLSLabelStack = 1 )
// A MPLSLabelStack represents a MPLS label stack.
type MPLSLabelStack struct { Class int // extension object class number
Type int // extension object sub-type
Labels []MPLSLabel }
// Len implements the Len method of Extension interface.
func (ls *MPLSLabelStack) Len(proto int) int { return 4 + (4 * len(ls.Labels)) }
// Marshal implements the Marshal method of Extension interface.
func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) { b := make([]byte, ls.Len(proto)) if err := ls.marshal(proto, b); err != nil { return nil, err } return b, nil }
func (ls *MPLSLabelStack) marshal(proto int, b []byte) error { l := ls.Len(proto) binary.BigEndian.PutUint16(b[:2], uint16(l)) b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack off := 4 for _, ll := range ls.Labels { b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0) b[off+2] |= byte(ll.TC << 1 & 0x0e) if ll.S { b[off+2] |= 0x1 } b[off+3] = byte(ll.TTL) off += 4 } return nil }
func parseMPLSLabelStack(b []byte) (Extension, error) { ls := &MPLSLabelStack{ Class: int(b[2]), Type: int(b[3]), } for b = b[4:]; len(b) >= 4; b = b[4:] { ll := MPLSLabel{ Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4, TC: int(b[2]&0x0e) >> 1, TTL: int(b[3]), } if b[2]&0x1 != 0 { ll.S = true } ls.Labels = append(ls.Labels, ll) } return ls, nil }
|