5
5
package ipv4
6
6
7
7
import (
8
+ "encoding/binary"
8
9
"fmt"
9
10
"net"
10
11
"runtime"
11
12
"syscall"
12
- "unsafe"
13
13
)
14
14
15
15
const (
@@ -64,17 +64,16 @@ func (h *Header) Marshal() ([]byte, error) {
64
64
flagsAndFragOff := (h .FragOff & 0x1fff ) | int (h .Flags << 13 )
65
65
switch runtime .GOOS {
66
66
case "darwin" , "dragonfly" , "freebsd" , "netbsd" :
67
- // TODO(mikio): fix potential misaligned memory access
68
- * (* uint16 )(unsafe .Pointer (& b [2 :3 ][0 ])) = uint16 (h .TotalLen )
69
- * (* uint16 )(unsafe .Pointer (& b [6 :7 ][0 ])) = uint16 (flagsAndFragOff )
67
+ nativeEndian .PutUint16 (b [2 :4 ], uint16 (h .TotalLen ))
68
+ nativeEndian .PutUint16 (b [6 :8 ], uint16 (flagsAndFragOff ))
70
69
default :
71
- b [2 ], b [ 3 ] = byte (h .TotalLen >> 8 ), byte ( h . TotalLen )
72
- b [6 ], b [ 7 ] = byte (flagsAndFragOff >> 8 ), byte ( flagsAndFragOff )
70
+ binary . BigEndian . PutUint16 ( b [2 : 4 ], uint16 (h .TotalLen ) )
71
+ binary . BigEndian . PutUint16 ( b [6 : 8 ], uint16 (flagsAndFragOff ) )
73
72
}
74
- b [4 ], b [ 5 ] = byte (h .ID >> 8 ), byte ( h . ID )
73
+ binary . BigEndian . PutUint16 ( b [4 : 6 ], uint16 (h .ID ) )
75
74
b [8 ] = byte (h .TTL )
76
75
b [9 ] = byte (h .Protocol )
77
- b [10 ], b [ 11 ] = byte (h .Checksum >> 8 ), byte ( h . Checksum )
76
+ binary . BigEndian . PutUint16 ( b [10 : 12 ], uint16 (h .Checksum ) )
78
77
if ip := h .Src .To4 (); ip != nil {
79
78
copy (b [12 :16 ], ip [:net .IPv4len ])
80
79
}
@@ -89,9 +88,6 @@ func (h *Header) Marshal() ([]byte, error) {
89
88
return b , nil
90
89
}
91
90
92
- // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
93
- var freebsdVersion uint32
94
-
95
91
// ParseHeader parses b as an IPv4 header.
96
92
func ParseHeader (b []byte ) (* Header , error ) {
97
93
if len (b ) < HeaderLen {
@@ -105,30 +101,26 @@ func ParseHeader(b []byte) (*Header, error) {
105
101
Version : int (b [0 ] >> 4 ),
106
102
Len : hdrlen ,
107
103
TOS : int (b [1 ]),
108
- ID : int (b [4 ]) << 8 | int ( b [ 5 ] ),
104
+ ID : int (binary . BigEndian . Uint16 ( b [4 : 6 ]) ),
109
105
TTL : int (b [8 ]),
110
106
Protocol : int (b [9 ]),
111
- Checksum : int (b [10 ]) << 8 | int ( b [ 11 ] ),
107
+ Checksum : int (binary . BigEndian . Uint16 ( b [10 : 12 ]) ),
112
108
Src : net .IPv4 (b [12 ], b [13 ], b [14 ], b [15 ]),
113
109
Dst : net .IPv4 (b [16 ], b [17 ], b [18 ], b [19 ]),
114
110
}
115
111
switch runtime .GOOS {
116
112
case "darwin" , "dragonfly" , "netbsd" :
117
- // TODO(mikio): fix potential misaligned memory access
118
- h .TotalLen = int (* (* uint16 )(unsafe .Pointer (& b [2 :3 ][0 ]))) + hdrlen
119
- // TODO(mikio): fix potential misaligned memory access
120
- h .FragOff = int (* (* uint16 )(unsafe .Pointer (& b [6 :7 ][0 ])))
113
+ h .TotalLen = int (nativeEndian .Uint16 (b [2 :4 ])) + hdrlen
114
+ h .FragOff = int (nativeEndian .Uint16 (b [6 :8 ]))
121
115
case "freebsd" :
122
- // TODO(mikio): fix potential misaligned memory access
123
- h .TotalLen = int (* (* uint16 )(unsafe .Pointer (& b [2 :3 ][0 ])))
116
+ h .TotalLen = int (nativeEndian .Uint16 (b [2 :4 ]))
124
117
if freebsdVersion < 1000000 {
125
118
h .TotalLen += hdrlen
126
119
}
127
- // TODO(mikio): fix potential misaligned memory access
128
- h .FragOff = int (* (* uint16 )(unsafe .Pointer (& b [6 :7 ][0 ])))
120
+ h .FragOff = int (nativeEndian .Uint16 (b [6 :8 ]))
129
121
default :
130
- h .TotalLen = int (b [2 ]) << 8 | int ( b [ 3 ] )
131
- h .FragOff = int (b [6 ]) << 8 | int ( b [ 7 ] )
122
+ h .TotalLen = int (binary . BigEndian . Uint16 ( b [2 : 4 ]) )
123
+ h .FragOff = int (binary . BigEndian . Uint16 ( b [6 : 8 ]) )
132
124
}
133
125
h .Flags = HeaderFlags (h .FragOff & 0xe000 ) >> 13
134
126
h .FragOff = h .FragOff & 0x1fff
0 commit comments