update packaging
[platform/core/system/edge-orchestration.git] / vendor / golang.org / x / net / icmp / ipv4.go
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 icmp
6
7 import (
8         "encoding/binary"
9         "net"
10         "runtime"
11
12         "golang.org/x/net/internal/socket"
13         "golang.org/x/net/ipv4"
14 )
15
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
19
20 // ParseIPv4Header returns the IPv4 header of the IPv4 packet that
21 // triggered an ICMP error message.
22 // This is found in the Data field of the ICMP error message body.
23 //
24 // The provided b must be in the format used by a raw ICMP socket on
25 // the local system.
26 // This may differ from the wire format, and the format used by a raw
27 // IP socket, depending on the system.
28 //
29 // To parse an IPv6 header, use ipv6.ParseHeader.
30 func ParseIPv4Header(b []byte) (*ipv4.Header, error) {
31         if len(b) < ipv4.HeaderLen {
32                 return nil, errHeaderTooShort
33         }
34         hdrlen := int(b[0]&0x0f) << 2
35         if hdrlen > len(b) {
36                 return nil, errBufferTooShort
37         }
38         h := &ipv4.Header{
39                 Version:  int(b[0] >> 4),
40                 Len:      hdrlen,
41                 TOS:      int(b[1]),
42                 ID:       int(binary.BigEndian.Uint16(b[4:6])),
43                 FragOff:  int(binary.BigEndian.Uint16(b[6:8])),
44                 TTL:      int(b[8]),
45                 Protocol: int(b[9]),
46                 Checksum: int(binary.BigEndian.Uint16(b[10:12])),
47                 Src:      net.IPv4(b[12], b[13], b[14], b[15]),
48                 Dst:      net.IPv4(b[16], b[17], b[18], b[19]),
49         }
50         switch runtime.GOOS {
51         case "darwin":
52                 h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
53         case "freebsd":
54                 if freebsdVersion >= 1000000 {
55                         h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
56                 } else {
57                         h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
58                 }
59         default:
60                 h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
61         }
62         h.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13
63         h.FragOff = h.FragOff & 0x1fff
64         if hdrlen-ipv4.HeaderLen > 0 {
65                 h.Options = make([]byte, hdrlen-ipv4.HeaderLen)
66                 copy(h.Options, b[ipv4.HeaderLen:])
67         }
68         return h, nil
69 }