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.
12 "golang.org/x/net/internal/socket"
13 "golang.org/x/net/ipv4"
16 // freebsdVersion is set in sys_freebsd.go.
17 // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
18 var freebsdVersion uint32
20 // ParseIPv4Header parses b as an IPv4 header of ICMP error message
21 // invoking packet, which is contained in ICMP error message.
22 func ParseIPv4Header(b []byte) (*ipv4.Header, error) {
23 if len(b) < ipv4.HeaderLen {
24 return nil, errHeaderTooShort
26 hdrlen := int(b[0]&0x0f) << 2
28 return nil, errBufferTooShort
31 Version: int(b[0] >> 4),
34 ID: int(binary.BigEndian.Uint16(b[4:6])),
35 FragOff: int(binary.BigEndian.Uint16(b[6:8])),
38 Checksum: int(binary.BigEndian.Uint16(b[10:12])),
39 Src: net.IPv4(b[12], b[13], b[14], b[15]),
40 Dst: net.IPv4(b[16], b[17], b[18], b[19]),
44 h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
46 if freebsdVersion >= 1000000 {
47 h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
49 h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
52 h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
54 h.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13
55 h.FragOff = h.FragOff & 0x1fff
56 if hdrlen-ipv4.HeaderLen > 0 {
57 h.Options = make([]byte, hdrlen-ipv4.HeaderLen)
58 copy(h.Options, b[ipv4.HeaderLen:])