github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/icmp/ipv4.go (about) 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 "net" 9 "runtime" 10 "unsafe" 11 12 "golang.org/x/net/ipv4" 13 ) 14 15 // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. 16 var freebsdVersion uint32 17 18 // ParseIPv4Header parses b as an IPv4 header of ICMP error message 19 // invoking packet, which is contained in ICMP error message. 20 func ParseIPv4Header(b []byte) (*ipv4.Header, error) { 21 if len(b) < ipv4.HeaderLen { 22 return nil, errHeaderTooShort 23 } 24 hdrlen := int(b[0]&0x0f) << 2 25 if hdrlen > len(b) { 26 return nil, errBufferTooShort 27 } 28 h := &ipv4.Header{ 29 Version: int(b[0] >> 4), 30 Len: hdrlen, 31 TOS: int(b[1]), 32 ID: int(b[4])<<8 | int(b[5]), 33 FragOff: int(b[6])<<8 | int(b[7]), 34 TTL: int(b[8]), 35 Protocol: int(b[9]), 36 Checksum: int(b[10])<<8 | int(b[11]), 37 Src: net.IPv4(b[12], b[13], b[14], b[15]), 38 Dst: net.IPv4(b[16], b[17], b[18], b[19]), 39 } 40 switch runtime.GOOS { 41 case "darwin": 42 // TODO(mikio): fix potential misaligned memory access 43 h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) 44 case "freebsd": 45 if freebsdVersion >= 1000000 { 46 h.TotalLen = int(b[2])<<8 | int(b[3]) 47 } else { 48 // TODO(mikio): fix potential misaligned memory access 49 h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) 50 } 51 default: 52 h.TotalLen = int(b[2])<<8 | int(b[3]) 53 } 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:]) 59 } 60 return h, nil 61 }