|
@@ -5,11 +5,11 @@
|
|
|
package ipv4
|
|
package ipv4
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
|
+ "encoding/binary"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"net"
|
|
"net"
|
|
|
"runtime"
|
|
"runtime"
|
|
|
"syscall"
|
|
"syscall"
|
|
|
- "unsafe"
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
const (
|
|
@@ -64,17 +64,16 @@ func (h *Header) Marshal() ([]byte, error) {
|
|
|
flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
|
|
flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
|
|
|
switch runtime.GOOS {
|
|
switch runtime.GOOS {
|
|
|
case "darwin", "dragonfly", "freebsd", "netbsd":
|
|
case "darwin", "dragonfly", "freebsd", "netbsd":
|
|
|
- // TODO(mikio): fix potential misaligned memory access
|
|
|
|
|
- *(*uint16)(unsafe.Pointer(&b[2:3][0])) = uint16(h.TotalLen)
|
|
|
|
|
- *(*uint16)(unsafe.Pointer(&b[6:7][0])) = uint16(flagsAndFragOff)
|
|
|
|
|
|
|
+ nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
|
|
|
|
|
+ nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
|
|
|
default:
|
|
default:
|
|
|
- b[2], b[3] = byte(h.TotalLen>>8), byte(h.TotalLen)
|
|
|
|
|
- b[6], b[7] = byte(flagsAndFragOff>>8), byte(flagsAndFragOff)
|
|
|
|
|
|
|
+ binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
|
|
|
|
|
+ binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
|
|
|
}
|
|
}
|
|
|
- b[4], b[5] = byte(h.ID>>8), byte(h.ID)
|
|
|
|
|
|
|
+ binary.BigEndian.PutUint16(b[4:6], uint16(h.ID))
|
|
|
b[8] = byte(h.TTL)
|
|
b[8] = byte(h.TTL)
|
|
|
b[9] = byte(h.Protocol)
|
|
b[9] = byte(h.Protocol)
|
|
|
- b[10], b[11] = byte(h.Checksum>>8), byte(h.Checksum)
|
|
|
|
|
|
|
+ binary.BigEndian.PutUint16(b[10:12], uint16(h.Checksum))
|
|
|
if ip := h.Src.To4(); ip != nil {
|
|
if ip := h.Src.To4(); ip != nil {
|
|
|
copy(b[12:16], ip[:net.IPv4len])
|
|
copy(b[12:16], ip[:net.IPv4len])
|
|
|
}
|
|
}
|
|
@@ -89,9 +88,6 @@ func (h *Header) Marshal() ([]byte, error) {
|
|
|
return b, nil
|
|
return b, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
|
|
|
|
|
-var freebsdVersion uint32
|
|
|
|
|
-
|
|
|
|
|
// ParseHeader parses b as an IPv4 header.
|
|
// ParseHeader parses b as an IPv4 header.
|
|
|
func ParseHeader(b []byte) (*Header, error) {
|
|
func ParseHeader(b []byte) (*Header, error) {
|
|
|
if len(b) < HeaderLen {
|
|
if len(b) < HeaderLen {
|
|
@@ -105,30 +101,26 @@ func ParseHeader(b []byte) (*Header, error) {
|
|
|
Version: int(b[0] >> 4),
|
|
Version: int(b[0] >> 4),
|
|
|
Len: hdrlen,
|
|
Len: hdrlen,
|
|
|
TOS: int(b[1]),
|
|
TOS: int(b[1]),
|
|
|
- ID: int(b[4])<<8 | int(b[5]),
|
|
|
|
|
|
|
+ ID: int(binary.BigEndian.Uint16(b[4:6])),
|
|
|
TTL: int(b[8]),
|
|
TTL: int(b[8]),
|
|
|
Protocol: int(b[9]),
|
|
Protocol: int(b[9]),
|
|
|
- Checksum: int(b[10])<<8 | int(b[11]),
|
|
|
|
|
|
|
+ Checksum: int(binary.BigEndian.Uint16(b[10:12])),
|
|
|
Src: net.IPv4(b[12], b[13], b[14], b[15]),
|
|
Src: net.IPv4(b[12], b[13], b[14], b[15]),
|
|
|
Dst: net.IPv4(b[16], b[17], b[18], b[19]),
|
|
Dst: net.IPv4(b[16], b[17], b[18], b[19]),
|
|
|
}
|
|
}
|
|
|
switch runtime.GOOS {
|
|
switch runtime.GOOS {
|
|
|
case "darwin", "dragonfly", "netbsd":
|
|
case "darwin", "dragonfly", "netbsd":
|
|
|
- // TODO(mikio): fix potential misaligned memory access
|
|
|
|
|
- h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) + hdrlen
|
|
|
|
|
- // TODO(mikio): fix potential misaligned memory access
|
|
|
|
|
- h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[6:7][0])))
|
|
|
|
|
|
|
+ h.TotalLen = int(nativeEndian.Uint16(b[2:4])) + hdrlen
|
|
|
|
|
+ h.FragOff = int(nativeEndian.Uint16(b[6:8]))
|
|
|
case "freebsd":
|
|
case "freebsd":
|
|
|
- // TODO(mikio): fix potential misaligned memory access
|
|
|
|
|
- h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0])))
|
|
|
|
|
|
|
+ h.TotalLen = int(nativeEndian.Uint16(b[2:4]))
|
|
|
if freebsdVersion < 1000000 {
|
|
if freebsdVersion < 1000000 {
|
|
|
h.TotalLen += hdrlen
|
|
h.TotalLen += hdrlen
|
|
|
}
|
|
}
|
|
|
- // TODO(mikio): fix potential misaligned memory access
|
|
|
|
|
- h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[6:7][0])))
|
|
|
|
|
|
|
+ h.FragOff = int(nativeEndian.Uint16(b[6:8]))
|
|
|
default:
|
|
default:
|
|
|
- h.TotalLen = int(b[2])<<8 | int(b[3])
|
|
|
|
|
- h.FragOff = int(b[6])<<8 | int(b[7])
|
|
|
|
|
|
|
+ h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
|
|
|
|
|
+ h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
|
|
|
}
|
|
}
|
|
|
h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13
|
|
h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13
|
|
|
h.FragOff = h.FragOff & 0x1fff
|
|
h.FragOff = h.FragOff & 0x1fff
|