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