Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ipv4 | 5 package ipv4 |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
9 "fmt" | 9 "fmt" |
10 "net" | 10 "net" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 posTTL = 8 // time-to-live | 46 posTTL = 8 // time-to-live |
47 posProtocol = 9 // next protocol | 47 posProtocol = 9 // next protocol |
48 posChecksum = 10 // checksum | 48 posChecksum = 10 // checksum |
49 posSrc = 12 // source address | 49 posSrc = 12 // source address |
50 posDst = 16 // destination address | 50 posDst = 16 // destination address |
51 ) | 51 ) |
52 | 52 |
53 type HeaderFlags int | 53 type HeaderFlags int |
54 | 54 |
55 const ( | 55 const ( |
56 » DontFragment HeaderFlags = 1 << iota // don't Fragment flag | 56 » MoreFragments HeaderFlags = 1 << iota // more fragments flag |
57 » MoreFragments // more Fragments flag | 57 » DontFragment // don't fragment flag |
58 ) | 58 ) |
59 | 59 |
60 // A Header represents an IPv4 header. | 60 // A Header represents an IPv4 header. |
61 type Header struct { | 61 type Header struct { |
62 Version int // protocol version | 62 Version int // protocol version |
63 Len int // header length | 63 Len int // header length |
64 TOS int // type-of-service | 64 TOS int // type-of-service |
65 TotalLen int // packet total length | 65 TotalLen int // packet total length |
66 ID int // identification | 66 ID int // identification |
67 Flags HeaderFlags // flags | 67 Flags HeaderFlags // flags |
68 FragOff int // fragment offset | 68 FragOff int // fragment offset |
69 TTL int // time-to-live | 69 TTL int // time-to-live |
70 Protocol int // next protocol | 70 Protocol int // next protocol |
71 Checksum int // checksum | 71 Checksum int // checksum |
72 Src net.IP // source address | 72 Src net.IP // source address |
73 Dst net.IP // destination address | 73 Dst net.IP // destination address |
74 Options []byte // options, extension headers | 74 Options []byte // options, extension headers |
75 } | 75 } |
76 | 76 |
77 func (h *Header) String() string { | 77 func (h *Header) String() string { |
78 if h == nil { | 78 if h == nil { |
79 return "<nil>" | 79 return "<nil>" |
80 } | 80 } |
81 » return fmt.Sprintf("ver: %v, hdrlen: %v, tos: %#x, totallen: %v, id: %#x , fragoff: %#x, ttl: %v, proto: %v, cksum: %#x, src: %v, dst: %v", h.Version, h. Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst) | 81 » return fmt.Sprintf("ver: %v, hdrlen: %v, tos: %#x, totallen: %v, id: %#x , flags: %#x, fragoff: %#x, ttl: %v, proto: %v, cksum: %#x, src: %v, dst: %v", h .Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst) |
mikio
2013/10/07 16:03:53
go tool vet says:
header.go:81: wrong number of ar
marant
2013/10/07 17:54:36
Done.
| |
82 } | 82 } |
83 | 83 |
84 // Please refer to the online manual; IP(4) on Darwin, FreeBSD and | 84 // Please refer to the online manual; IP(4) on Darwin, FreeBSD and |
85 // OpenBSD. IP(7) on Linux. | 85 // OpenBSD. IP(7) on Linux. |
86 const supportsNewIPInput = runtime.GOOS == "linux" || runtime.GOOS == "openbsd" | 86 const supportsNewIPInput = runtime.GOOS == "linux" || runtime.GOOS == "openbsd" |
87 | 87 |
88 // Marshal returns the binary encoding of the IPv4 header h. | 88 // Marshal returns the binary encoding of the IPv4 header h. |
89 func (h *Header) Marshal() ([]byte, error) { | 89 func (h *Header) Marshal() ([]byte, error) { |
90 if h == nil { | 90 if h == nil { |
91 return nil, syscall.EINVAL | 91 return nil, syscall.EINVAL |
92 } | 92 } |
93 if h.Len < HeaderLen { | 93 if h.Len < HeaderLen { |
94 return nil, errHeaderTooShort | 94 return nil, errHeaderTooShort |
95 } | 95 } |
96 hdrlen := HeaderLen + len(h.Options) | 96 hdrlen := HeaderLen + len(h.Options) |
97 b := make([]byte, hdrlen) | 97 b := make([]byte, hdrlen) |
98 b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f)) | 98 b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f)) |
99 b[posTOS] = byte(h.TOS) | 99 b[posTOS] = byte(h.TOS) |
100 » flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<14) | 100 » flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13) |
mikio
2013/10/07 16:03:53
h.Flags<<14 doesn't look correct to me.
Does your
marant
2013/10/07 17:54:36
Yes, you are correct. I had the flags defined in t
| |
101 if supportsNewIPInput { | 101 if supportsNewIPInput { |
102 b[posTotalLen], b[posTotalLen+1] = byte(h.TotalLen>>8), byte(h.T otalLen) | 102 b[posTotalLen], b[posTotalLen+1] = byte(h.TotalLen>>8), byte(h.T otalLen) |
103 b[posFragOff], b[posFragOff+1] = byte(flagsAndFragOff>>8), byte( flagsAndFragOff) | 103 b[posFragOff], b[posFragOff+1] = byte(flagsAndFragOff>>8), byte( flagsAndFragOff) |
104 } else { | 104 } else { |
105 *(*uint16)(unsafe.Pointer(&b[posTotalLen : posTotalLen+1][0])) = uint16(h.TotalLen) | 105 *(*uint16)(unsafe.Pointer(&b[posTotalLen : posTotalLen+1][0])) = uint16(h.TotalLen) |
106 *(*uint16)(unsafe.Pointer(&b[posFragOff : posFragOff+1][0])) = u int16(flagsAndFragOff) | 106 *(*uint16)(unsafe.Pointer(&b[posFragOff : posFragOff+1][0])) = u int16(flagsAndFragOff) |
107 } | 107 } |
108 b[posID], b[posID+1] = byte(h.ID>>8), byte(h.ID) | 108 b[posID], b[posID+1] = byte(h.ID>>8), byte(h.ID) |
109 b[posTTL] = byte(h.TTL) | 109 b[posTTL] = byte(h.TTL) |
110 b[posProtocol] = byte(h.Protocol) | 110 b[posProtocol] = byte(h.Protocol) |
(...skipping 26 matching lines...) Expand all Loading... | |
137 h.Len = hdrlen | 137 h.Len = hdrlen |
138 h.TOS = int(b[posTOS]) | 138 h.TOS = int(b[posTOS]) |
139 if supportsNewIPInput { | 139 if supportsNewIPInput { |
140 h.TotalLen = int(b[posTotalLen])<<8 | int(b[posTotalLen+1]) | 140 h.TotalLen = int(b[posTotalLen])<<8 | int(b[posTotalLen+1]) |
141 h.FragOff = int(b[posFragOff])<<8 | int(b[posFragOff+1]) | 141 h.FragOff = int(b[posFragOff])<<8 | int(b[posFragOff+1]) |
142 } else { | 142 } else { |
143 h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[posTotalLen : posT otalLen+1][0]))) | 143 h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[posTotalLen : posT otalLen+1][0]))) |
144 h.TotalLen += hdrlen | 144 h.TotalLen += hdrlen |
145 h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[posFragOff : posFra gOff+1][0]))) | 145 h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[posFragOff : posFra gOff+1][0]))) |
146 } | 146 } |
147 » h.Flags = HeaderFlags(h.FragOff&0xe000) >> 14 | 147 » h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13 |
148 h.FragOff = h.FragOff & 0x1fff | 148 h.FragOff = h.FragOff & 0x1fff |
149 h.ID = int(b[posID])<<8 | int(b[posID+1]) | 149 h.ID = int(b[posID])<<8 | int(b[posID+1]) |
150 h.TTL = int(b[posTTL]) | 150 h.TTL = int(b[posTTL]) |
151 h.Protocol = int(b[posProtocol]) | 151 h.Protocol = int(b[posProtocol]) |
152 h.Checksum = int(b[posChecksum])<<8 | int(b[posChecksum+1]) | 152 h.Checksum = int(b[posChecksum])<<8 | int(b[posChecksum+1]) |
153 h.Src = net.IPv4(b[posSrc], b[posSrc+1], b[posSrc+2], b[posSrc+3]) | 153 h.Src = net.IPv4(b[posSrc], b[posSrc+1], b[posSrc+2], b[posSrc+3]) |
154 h.Dst = net.IPv4(b[posDst], b[posDst+1], b[posDst+2], b[posDst+3]) | 154 h.Dst = net.IPv4(b[posDst], b[posDst+1], b[posDst+2], b[posDst+3]) |
155 if hdrlen-HeaderLen > 0 { | 155 if hdrlen-HeaderLen > 0 { |
156 h.Options = make([]byte, hdrlen-HeaderLen) | 156 h.Options = make([]byte, hdrlen-HeaderLen) |
157 copy(h.Options, b[HeaderLen:]) | 157 copy(h.Options, b[HeaderLen:]) |
158 } | 158 } |
159 return h, nil | 159 return h, nil |
160 } | 160 } |
LEFT | RIGHT |