|  | // 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 | 
|  | } |