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
5package ipv6
6
7import (
8	"encoding/binary"
9	"fmt"
10	"net"
11)
12
13const (
14	Version   = 6  // protocol version
15	HeaderLen = 40 // header length
16)
17
18// A Header represents an IPv6 base header.
19type 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
30func (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.
38func 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}
56