icmp6msg.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license
  5. // that can be found in the LICENSE file in the root of the source
  6. // tree.
  7. package layers
  8. import (
  9. "encoding/binary"
  10. "encoding/hex"
  11. "errors"
  12. "fmt"
  13. "net"
  14. "time"
  15. "github.com/google/gopacket"
  16. )
  17. // Based on RFC 4861
  18. // ICMPv6Opt indicate how to decode the data associated with each ICMPv6Option.
  19. type ICMPv6Opt uint8
  20. const (
  21. _ ICMPv6Opt = iota
  22. // ICMPv6OptSourceAddress contains the link-layer address of the sender of
  23. // the packet. It is used in the Neighbor Solicitation, Router
  24. // Solicitation, and Router Advertisement packets. Must be ignored for other
  25. // Neighbor discovery messages.
  26. ICMPv6OptSourceAddress
  27. // ICMPv6OptTargetAddress contains the link-layer address of the target. It
  28. // is used in Neighbor Advertisement and Redirect packets. Must be ignored
  29. // for other Neighbor discovery messages.
  30. ICMPv6OptTargetAddress
  31. // ICMPv6OptPrefixInfo provides hosts with on-link prefixes and prefixes
  32. // for Address Autoconfiguration. The Prefix Information option appears in
  33. // Router Advertisement packets and MUST be silently ignored for other
  34. // messages.
  35. ICMPv6OptPrefixInfo
  36. // ICMPv6OptRedirectedHeader is used in Redirect messages and contains all
  37. // or part of the packet that is being redirected.
  38. ICMPv6OptRedirectedHeader
  39. // ICMPv6OptMTU is used in Router Advertisement messages to ensure that all
  40. // nodes on a link use the same MTU value in those cases where the link MTU
  41. // is not well known. This option MUST be silently ignored for other
  42. // Neighbor Discovery messages.
  43. ICMPv6OptMTU
  44. )
  45. // ICMPv6RouterSolicitation is sent by hosts to find routers.
  46. type ICMPv6RouterSolicitation struct {
  47. BaseLayer
  48. Options ICMPv6Options
  49. }
  50. // ICMPv6RouterAdvertisement is sent by routers in response to Solicitation.
  51. type ICMPv6RouterAdvertisement struct {
  52. BaseLayer
  53. HopLimit uint8
  54. Flags uint8
  55. RouterLifetime uint16
  56. ReachableTime uint32
  57. RetransTimer uint32
  58. Options ICMPv6Options
  59. }
  60. // ICMPv6NeighborSolicitation is sent to request the link-layer address of a
  61. // target node.
  62. type ICMPv6NeighborSolicitation struct {
  63. BaseLayer
  64. TargetAddress net.IP
  65. Options ICMPv6Options
  66. }
  67. // ICMPv6NeighborAdvertisement is sent by nodes in response to Solicitation.
  68. type ICMPv6NeighborAdvertisement struct {
  69. BaseLayer
  70. Flags uint8
  71. TargetAddress net.IP
  72. Options ICMPv6Options
  73. }
  74. // ICMPv6Redirect is sent by routers to inform hosts of a better first-hop node
  75. // on the path to a destination.
  76. type ICMPv6Redirect struct {
  77. BaseLayer
  78. TargetAddress net.IP
  79. DestinationAddress net.IP
  80. Options ICMPv6Options
  81. }
  82. // ICMPv6Option contains the type and data for a single option.
  83. type ICMPv6Option struct {
  84. Type ICMPv6Opt
  85. Data []byte
  86. }
  87. // ICMPv6Options is a slice of ICMPv6Option.
  88. type ICMPv6Options []ICMPv6Option
  89. func (i ICMPv6Opt) String() string {
  90. switch i {
  91. case ICMPv6OptSourceAddress:
  92. return "SourceAddress"
  93. case ICMPv6OptTargetAddress:
  94. return "TargetAddress"
  95. case ICMPv6OptPrefixInfo:
  96. return "PrefixInfo"
  97. case ICMPv6OptRedirectedHeader:
  98. return "RedirectedHeader"
  99. case ICMPv6OptMTU:
  100. return "MTU"
  101. default:
  102. return fmt.Sprintf("Unknown(%d)", i)
  103. }
  104. }
  105. // LayerType returns LayerTypeICMPv6.
  106. func (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType {
  107. return LayerTypeICMPv6RouterSolicitation
  108. }
  109. // NextLayerType returns the layer type contained by this DecodingLayer.
  110. func (i *ICMPv6RouterSolicitation) NextLayerType() gopacket.LayerType {
  111. return gopacket.LayerTypePayload
  112. }
  113. // DecodeFromBytes decodes the given bytes into this layer.
  114. func (i *ICMPv6RouterSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  115. // first 4 bytes are reserved followed by options
  116. if len(data) < 4 {
  117. df.SetTruncated()
  118. return errors.New("ICMP layer less then 4 bytes for ICMPv6 router solicitation")
  119. }
  120. // truncate old options
  121. i.Options = i.Options[:0]
  122. return i.Options.DecodeFromBytes(data[4:], df)
  123. }
  124. // SerializeTo writes the serialized form of this layer into the
  125. // SerializationBuffer, implementing gopacket.SerializableLayer.
  126. // See the docs for gopacket.SerializableLayer for more info.
  127. func (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  128. if err := i.Options.SerializeTo(b, opts); err != nil {
  129. return err
  130. }
  131. buf, err := b.PrependBytes(4)
  132. if err != nil {
  133. return err
  134. }
  135. copy(buf, lotsOfZeros[:4])
  136. return nil
  137. }
  138. // LayerType returns LayerTypeICMPv6RouterAdvertisement.
  139. func (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType {
  140. return LayerTypeICMPv6RouterAdvertisement
  141. }
  142. // NextLayerType returns the layer type contained by this DecodingLayer.
  143. func (i *ICMPv6RouterAdvertisement) NextLayerType() gopacket.LayerType {
  144. return gopacket.LayerTypePayload
  145. }
  146. // DecodeFromBytes decodes the given bytes into this layer.
  147. func (i *ICMPv6RouterAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  148. if len(data) < 12 {
  149. df.SetTruncated()
  150. return errors.New("ICMP layer less then 12 bytes for ICMPv6 router advertisement")
  151. }
  152. i.HopLimit = uint8(data[0])
  153. // M, O bit followed by 6 reserved bits
  154. i.Flags = uint8(data[1])
  155. i.RouterLifetime = binary.BigEndian.Uint16(data[2:4])
  156. i.ReachableTime = binary.BigEndian.Uint32(data[4:8])
  157. i.RetransTimer = binary.BigEndian.Uint32(data[8:12])
  158. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  159. // truncate old options
  160. i.Options = i.Options[:0]
  161. return i.Options.DecodeFromBytes(data[12:], df)
  162. }
  163. // SerializeTo writes the serialized form of this layer into the
  164. // SerializationBuffer, implementing gopacket.SerializableLayer.
  165. // See the docs for gopacket.SerializableLayer for more info.
  166. func (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  167. if err := i.Options.SerializeTo(b, opts); err != nil {
  168. return err
  169. }
  170. buf, err := b.PrependBytes(12)
  171. if err != nil {
  172. return err
  173. }
  174. buf[0] = byte(i.HopLimit)
  175. buf[1] = byte(i.Flags)
  176. binary.BigEndian.PutUint16(buf[2:], i.RouterLifetime)
  177. binary.BigEndian.PutUint32(buf[4:], i.ReachableTime)
  178. binary.BigEndian.PutUint32(buf[8:], i.RetransTimer)
  179. return nil
  180. }
  181. // ManagedAddressConfig is true when addresses are available via DHCPv6. If
  182. // set, the OtherConfig flag is redundant.
  183. func (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool {
  184. return i.Flags&0x80 != 1
  185. }
  186. // OtherConfig is true when there is other configuration information available
  187. // via DHCPv6. For example, DNS-related information.
  188. func (i *ICMPv6RouterAdvertisement) OtherConfig() bool {
  189. return i.Flags&0x40 != 1
  190. }
  191. // LayerType returns LayerTypeICMPv6NeighborSolicitation.
  192. func (i *ICMPv6NeighborSolicitation) LayerType() gopacket.LayerType {
  193. return LayerTypeICMPv6NeighborSolicitation
  194. }
  195. // NextLayerType returns the layer type contained by this DecodingLayer.
  196. func (i *ICMPv6NeighborSolicitation) NextLayerType() gopacket.LayerType {
  197. return gopacket.LayerTypePayload
  198. }
  199. // DecodeFromBytes decodes the given bytes into this layer.
  200. func (i *ICMPv6NeighborSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  201. if len(data) < 20 {
  202. df.SetTruncated()
  203. return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor solicitation")
  204. }
  205. i.TargetAddress = net.IP(data[4:20])
  206. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  207. // truncate old options
  208. i.Options = i.Options[:0]
  209. return i.Options.DecodeFromBytes(data[20:], df)
  210. }
  211. // SerializeTo writes the serialized form of this layer into the
  212. // SerializationBuffer, implementing gopacket.SerializableLayer.
  213. // See the docs for gopacket.SerializableLayer for more info.
  214. func (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  215. if err := i.Options.SerializeTo(b, opts); err != nil {
  216. return err
  217. }
  218. buf, err := b.PrependBytes(20)
  219. if err != nil {
  220. return err
  221. }
  222. copy(buf, lotsOfZeros[:4])
  223. copy(buf[4:], i.TargetAddress)
  224. return nil
  225. }
  226. // LayerType returns LayerTypeICMPv6NeighborAdvertisement.
  227. func (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType {
  228. return LayerTypeICMPv6NeighborAdvertisement
  229. }
  230. // NextLayerType returns the layer type contained by this DecodingLayer.
  231. func (i *ICMPv6NeighborAdvertisement) NextLayerType() gopacket.LayerType {
  232. return gopacket.LayerTypePayload
  233. }
  234. // DecodeFromBytes decodes the given bytes into this layer.
  235. func (i *ICMPv6NeighborAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  236. if len(data) < 20 {
  237. df.SetTruncated()
  238. return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor advertisement")
  239. }
  240. i.Flags = uint8(data[0])
  241. i.TargetAddress = net.IP(data[4:20])
  242. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  243. // truncate old options
  244. i.Options = i.Options[:0]
  245. return i.Options.DecodeFromBytes(data[20:], df)
  246. }
  247. // SerializeTo writes the serialized form of this layer into the
  248. // SerializationBuffer, implementing gopacket.SerializableLayer.
  249. // See the docs for gopacket.SerializableLayer for more info.
  250. func (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  251. if err := i.Options.SerializeTo(b, opts); err != nil {
  252. return err
  253. }
  254. buf, err := b.PrependBytes(20)
  255. if err != nil {
  256. return err
  257. }
  258. buf[0] = byte(i.Flags)
  259. copy(buf[1:], lotsOfZeros[:3])
  260. copy(buf[4:], i.TargetAddress)
  261. return nil
  262. }
  263. // Router indicates whether the sender is a router or not.
  264. func (i *ICMPv6NeighborAdvertisement) Router() bool {
  265. return i.Flags&0x80 != 0
  266. }
  267. // Solicited indicates whether the advertisement was solicited or not.
  268. func (i *ICMPv6NeighborAdvertisement) Solicited() bool {
  269. return i.Flags&0x40 != 0
  270. }
  271. // Override indicates whether the advertisement should Override an existing
  272. // cache entry.
  273. func (i *ICMPv6NeighborAdvertisement) Override() bool {
  274. return i.Flags&0x20 != 0
  275. }
  276. // LayerType returns LayerTypeICMPv6Redirect.
  277. func (i *ICMPv6Redirect) LayerType() gopacket.LayerType {
  278. return LayerTypeICMPv6Redirect
  279. }
  280. // NextLayerType returns the layer type contained by this DecodingLayer.
  281. func (i *ICMPv6Redirect) NextLayerType() gopacket.LayerType {
  282. return gopacket.LayerTypePayload
  283. }
  284. // DecodeFromBytes decodes the given bytes into this layer.
  285. func (i *ICMPv6Redirect) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  286. if len(data) < 36 {
  287. df.SetTruncated()
  288. return errors.New("ICMP layer less then 36 bytes for ICMPv6 redirect")
  289. }
  290. i.TargetAddress = net.IP(data[4:20])
  291. i.DestinationAddress = net.IP(data[20:36])
  292. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  293. // truncate old options
  294. i.Options = i.Options[:0]
  295. return i.Options.DecodeFromBytes(data[36:], df)
  296. }
  297. // SerializeTo writes the serialized form of this layer into the
  298. // SerializationBuffer, implementing gopacket.SerializableLayer.
  299. // See the docs for gopacket.SerializableLayer for more info.
  300. func (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  301. if err := i.Options.SerializeTo(b, opts); err != nil {
  302. return err
  303. }
  304. buf, err := b.PrependBytes(36)
  305. if err != nil {
  306. return err
  307. }
  308. copy(buf, lotsOfZeros[:4])
  309. copy(buf[4:], i.TargetAddress)
  310. copy(buf[20:], i.DestinationAddress)
  311. return nil
  312. }
  313. func (i ICMPv6Option) String() string {
  314. hd := hex.EncodeToString(i.Data)
  315. if len(hd) > 0 {
  316. hd = " 0x" + hd
  317. }
  318. switch i.Type {
  319. case ICMPv6OptSourceAddress, ICMPv6OptTargetAddress:
  320. return fmt.Sprintf("ICMPv6Option(%s:%v)",
  321. i.Type,
  322. net.HardwareAddr(i.Data))
  323. case ICMPv6OptPrefixInfo:
  324. if len(i.Data) == 30 {
  325. prefixLen := uint8(i.Data[0])
  326. onLink := (i.Data[1]&0x80 != 0)
  327. autonomous := (i.Data[1]&0x40 != 0)
  328. validLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[2:6])) * time.Second
  329. preferredLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[6:10])) * time.Second
  330. prefix := net.IP(i.Data[14:])
  331. return fmt.Sprintf("ICMPv6Option(%s:%v/%v:%t:%t:%v:%v)",
  332. i.Type,
  333. prefix, prefixLen,
  334. onLink, autonomous,
  335. validLifetime, preferredLifetime)
  336. }
  337. case ICMPv6OptRedirectedHeader:
  338. // could invoke IP decoder on data... probably best not to
  339. break
  340. case ICMPv6OptMTU:
  341. if len(i.Data) == 6 {
  342. return fmt.Sprintf("ICMPv6Option(%s:%v)",
  343. i.Type,
  344. binary.BigEndian.Uint32(i.Data[2:]))
  345. }
  346. }
  347. return fmt.Sprintf("ICMPv6Option(%s:%s)", i.Type, hd)
  348. }
  349. // DecodeFromBytes decodes the given bytes into this layer.
  350. func (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  351. for len(data) > 0 {
  352. if len(data) < 2 {
  353. df.SetTruncated()
  354. return errors.New("ICMP layer less then 2 bytes for ICMPv6 message option")
  355. }
  356. // unit is 8 octets, convert to bytes
  357. length := int(data[1]) * 8
  358. if len(data) < length {
  359. df.SetTruncated()
  360. return fmt.Errorf("ICMP layer only %v bytes for ICMPv6 message option with length %v", len(data), length)
  361. }
  362. o := ICMPv6Option{
  363. Type: ICMPv6Opt(data[0]),
  364. Data: data[2:length],
  365. }
  366. // chop off option we just consumed
  367. data = data[length:]
  368. *i = append(*i, o)
  369. }
  370. return nil
  371. }
  372. // SerializeTo writes the serialized form of this layer into the
  373. // SerializationBuffer, implementing gopacket.SerializableLayer.
  374. // See the docs for gopacket.SerializableLayer for more info.
  375. func (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  376. for _, opt := range []ICMPv6Option(*i) {
  377. length := len(opt.Data) + 2
  378. buf, err := b.PrependBytes(length)
  379. if err != nil {
  380. return err
  381. }
  382. buf[0] = byte(opt.Type)
  383. buf[1] = byte(length / 8)
  384. copy(buf[2:], opt.Data)
  385. }
  386. return nil
  387. }
  388. func decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error {
  389. i := &ICMPv6RouterSolicitation{}
  390. return decodingLayerDecoder(i, data, p)
  391. }
  392. func decodeICMPv6RouterAdvertisement(data []byte, p gopacket.PacketBuilder) error {
  393. i := &ICMPv6RouterAdvertisement{}
  394. return decodingLayerDecoder(i, data, p)
  395. }
  396. func decodeICMPv6NeighborSolicitation(data []byte, p gopacket.PacketBuilder) error {
  397. i := &ICMPv6NeighborSolicitation{}
  398. return decodingLayerDecoder(i, data, p)
  399. }
  400. func decodeICMPv6NeighborAdvertisement(data []byte, p gopacket.PacketBuilder) error {
  401. i := &ICMPv6NeighborAdvertisement{}
  402. return decodingLayerDecoder(i, data, p)
  403. }
  404. func decodeICMPv6Redirect(data []byte, p gopacket.PacketBuilder) error {
  405. i := &ICMPv6Redirect{}
  406. return decodingLayerDecoder(i, data, p)
  407. }