David K. Bainbridge | 215e024 | 2017-09-05 23:18:24 -0700 | [diff] [blame] | 1 | // Copyright 2014 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 ipv6 |
| 6 | |
| 7 | import ( |
| 8 | "encoding/binary" |
| 9 | "fmt" |
| 10 | "net" |
| 11 | ) |
| 12 | |
| 13 | const ( |
| 14 | Version = 6 // protocol version |
| 15 | HeaderLen = 40 // header length |
| 16 | ) |
| 17 | |
| 18 | // A Header represents an IPv6 base header. |
| 19 | type Header struct { |
| 20 | Version int // protocol version |
| 21 | TrafficClass int // traffic class |
| 22 | FlowLabel int // flow label |
| 23 | PayloadLen int // payload length |
| 24 | NextHeader int // next header |
| 25 | HopLimit int // hop limit |
| 26 | Src net.IP // source address |
| 27 | Dst net.IP // destination address |
| 28 | } |
| 29 | |
| 30 | func (h *Header) String() string { |
| 31 | if h == nil { |
| 32 | return "<nil>" |
| 33 | } |
| 34 | 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) |
| 35 | } |
| 36 | |
| 37 | // ParseHeader parses b as an IPv6 base header. |
| 38 | func ParseHeader(b []byte) (*Header, error) { |
| 39 | if len(b) < HeaderLen { |
| 40 | return nil, errHeaderTooShort |
| 41 | } |
| 42 | h := &Header{ |
| 43 | Version: int(b[0]) >> 4, |
| 44 | TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4, |
| 45 | FlowLabel: int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]), |
| 46 | PayloadLen: int(binary.BigEndian.Uint16(b[4:6])), |
| 47 | NextHeader: int(b[6]), |
| 48 | HopLimit: int(b[7]), |
| 49 | } |
| 50 | h.Src = make(net.IP, net.IPv6len) |
| 51 | copy(h.Src, b[8:24]) |
| 52 | h.Dst = make(net.IP, net.IPv6len) |
| 53 | copy(h.Dst, b[24:40]) |
| 54 | return h, nil |
| 55 | } |