// Copyright 2014 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 ipv6 import ( "encoding/binary" "fmt" "net" ) const ( Version = 6 // protocol version HeaderLen = 40 // header length ) // A Header represents an IPv6 base header. type Header struct { Version int // protocol version TrafficClass int // traffic class FlowLabel int // flow label PayloadLen int // payload length NextHeader int // next header HopLimit int // hop limit Src net.IP // source address Dst net.IP // destination address } func (h *Header) String() string { if h == nil { return "<nil>" } return fmt.Sprintf("ver=%d tclass=%#x flowlbl=%#x payloadlen=%d nxthdr=%d hoplim=%d src=%v dst=%v", h.Version, h.TrafficClass, h.FlowLabel, h.PayloadLen, h.NextHeader, h.HopLimit, h.Src, h.Dst) } // ParseHeader parses b as an IPv6 base header. func ParseHeader(b []byte) (*Header, error) { if len(b) < HeaderLen { return nil, errHeaderTooShort } h := &Header{ Version: int(b[0]) >> 4, TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4, FlowLabel: int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]), PayloadLen: int(binary.BigEndian.Uint16(b[4:6])), NextHeader: int(b[6]), HopLimit: int(b[7]), } h.Src = make(net.IP, net.IPv6len) copy(h.Src, b[8:24]) h.Dst = make(net.IP, net.IPv6len) copy(h.Dst, b[24:40]) return h, nil }