icmp6msg.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  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. // ICMPv6Echo represents the structure of a ping.
  46. type ICMPv6Echo struct {
  47. BaseLayer
  48. Identifier uint16
  49. SeqNumber uint16
  50. }
  51. // ICMPv6RouterSolicitation is sent by hosts to find routers.
  52. type ICMPv6RouterSolicitation struct {
  53. BaseLayer
  54. Options ICMPv6Options
  55. }
  56. // ICMPv6RouterAdvertisement is sent by routers in response to Solicitation.
  57. type ICMPv6RouterAdvertisement struct {
  58. BaseLayer
  59. HopLimit uint8
  60. Flags uint8
  61. RouterLifetime uint16
  62. ReachableTime uint32
  63. RetransTimer uint32
  64. Options ICMPv6Options
  65. }
  66. // ICMPv6NeighborSolicitation is sent to request the link-layer address of a
  67. // target node.
  68. type ICMPv6NeighborSolicitation struct {
  69. BaseLayer
  70. TargetAddress net.IP
  71. Options ICMPv6Options
  72. }
  73. // ICMPv6NeighborAdvertisement is sent by nodes in response to Solicitation.
  74. type ICMPv6NeighborAdvertisement struct {
  75. BaseLayer
  76. Flags uint8
  77. TargetAddress net.IP
  78. Options ICMPv6Options
  79. }
  80. // ICMPv6Redirect is sent by routers to inform hosts of a better first-hop node
  81. // on the path to a destination.
  82. type ICMPv6Redirect struct {
  83. BaseLayer
  84. TargetAddress net.IP
  85. DestinationAddress net.IP
  86. Options ICMPv6Options
  87. }
  88. // ICMPv6Option contains the type and data for a single option.
  89. type ICMPv6Option struct {
  90. Type ICMPv6Opt
  91. Data []byte
  92. }
  93. // ICMPv6Options is a slice of ICMPv6Option.
  94. type ICMPv6Options []ICMPv6Option
  95. func (i ICMPv6Opt) String() string {
  96. switch i {
  97. case ICMPv6OptSourceAddress:
  98. return "SourceAddress"
  99. case ICMPv6OptTargetAddress:
  100. return "TargetAddress"
  101. case ICMPv6OptPrefixInfo:
  102. return "PrefixInfo"
  103. case ICMPv6OptRedirectedHeader:
  104. return "RedirectedHeader"
  105. case ICMPv6OptMTU:
  106. return "MTU"
  107. default:
  108. return fmt.Sprintf("Unknown(%d)", i)
  109. }
  110. }
  111. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  112. func (i *ICMPv6Echo) CanDecode() gopacket.LayerClass {
  113. return LayerTypeICMPv6Echo
  114. }
  115. // LayerType returns LayerTypeICMPv6Echo.
  116. func (i *ICMPv6Echo) LayerType() gopacket.LayerType {
  117. return LayerTypeICMPv6Echo
  118. }
  119. // NextLayerType returns the layer type contained by this DecodingLayer.
  120. func (i *ICMPv6Echo) NextLayerType() gopacket.LayerType {
  121. return gopacket.LayerTypePayload
  122. }
  123. // DecodeFromBytes decodes the given bytes into this layer.
  124. func (i *ICMPv6Echo) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  125. if len(data) < 4 {
  126. df.SetTruncated()
  127. return errors.New("ICMP layer less then 4 bytes for ICMPv6 Echo")
  128. }
  129. i.Identifier = binary.BigEndian.Uint16(data[0:2])
  130. i.SeqNumber = binary.BigEndian.Uint16(data[2:4])
  131. return nil
  132. }
  133. // SerializeTo writes the serialized form of this layer into the
  134. // SerializationBuffer, implementing gopacket.SerializableLayer.
  135. // See the docs for gopacket.SerializableLayer for more info.
  136. func (i *ICMPv6Echo) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  137. buf, err := b.PrependBytes(4)
  138. if err != nil {
  139. return err
  140. }
  141. binary.BigEndian.PutUint16(buf, i.Identifier)
  142. binary.BigEndian.PutUint16(buf[2:], i.SeqNumber)
  143. return nil
  144. }
  145. // LayerType returns LayerTypeICMPv6.
  146. func (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType {
  147. return LayerTypeICMPv6RouterSolicitation
  148. }
  149. // NextLayerType returns the layer type contained by this DecodingLayer.
  150. func (i *ICMPv6RouterSolicitation) NextLayerType() gopacket.LayerType {
  151. return gopacket.LayerTypePayload
  152. }
  153. // DecodeFromBytes decodes the given bytes into this layer.
  154. func (i *ICMPv6RouterSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  155. // first 4 bytes are reserved followed by options
  156. if len(data) < 4 {
  157. df.SetTruncated()
  158. return errors.New("ICMP layer less then 4 bytes for ICMPv6 router solicitation")
  159. }
  160. // truncate old options
  161. i.Options = i.Options[:0]
  162. return i.Options.DecodeFromBytes(data[4:], df)
  163. }
  164. // SerializeTo writes the serialized form of this layer into the
  165. // SerializationBuffer, implementing gopacket.SerializableLayer.
  166. // See the docs for gopacket.SerializableLayer for more info.
  167. func (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  168. if err := i.Options.SerializeTo(b, opts); err != nil {
  169. return err
  170. }
  171. buf, err := b.PrependBytes(4)
  172. if err != nil {
  173. return err
  174. }
  175. copy(buf, lotsOfZeros[:4])
  176. return nil
  177. }
  178. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  179. func (i *ICMPv6RouterSolicitation) CanDecode() gopacket.LayerClass {
  180. return LayerTypeICMPv6RouterSolicitation
  181. }
  182. // LayerType returns LayerTypeICMPv6RouterAdvertisement.
  183. func (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType {
  184. return LayerTypeICMPv6RouterAdvertisement
  185. }
  186. // NextLayerType returns the layer type contained by this DecodingLayer.
  187. func (i *ICMPv6RouterAdvertisement) NextLayerType() gopacket.LayerType {
  188. return gopacket.LayerTypePayload
  189. }
  190. // DecodeFromBytes decodes the given bytes into this layer.
  191. func (i *ICMPv6RouterAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  192. if len(data) < 12 {
  193. df.SetTruncated()
  194. return errors.New("ICMP layer less then 12 bytes for ICMPv6 router advertisement")
  195. }
  196. i.HopLimit = uint8(data[0])
  197. // M, O bit followed by 6 reserved bits
  198. i.Flags = uint8(data[1])
  199. i.RouterLifetime = binary.BigEndian.Uint16(data[2:4])
  200. i.ReachableTime = binary.BigEndian.Uint32(data[4:8])
  201. i.RetransTimer = binary.BigEndian.Uint32(data[8:12])
  202. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  203. // truncate old options
  204. i.Options = i.Options[:0]
  205. return i.Options.DecodeFromBytes(data[12:], df)
  206. }
  207. // SerializeTo writes the serialized form of this layer into the
  208. // SerializationBuffer, implementing gopacket.SerializableLayer.
  209. // See the docs for gopacket.SerializableLayer for more info.
  210. func (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  211. if err := i.Options.SerializeTo(b, opts); err != nil {
  212. return err
  213. }
  214. buf, err := b.PrependBytes(12)
  215. if err != nil {
  216. return err
  217. }
  218. buf[0] = byte(i.HopLimit)
  219. buf[1] = byte(i.Flags)
  220. binary.BigEndian.PutUint16(buf[2:], i.RouterLifetime)
  221. binary.BigEndian.PutUint32(buf[4:], i.ReachableTime)
  222. binary.BigEndian.PutUint32(buf[8:], i.RetransTimer)
  223. return nil
  224. }
  225. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  226. func (i *ICMPv6RouterAdvertisement) CanDecode() gopacket.LayerClass {
  227. return LayerTypeICMPv6RouterAdvertisement
  228. }
  229. // ManagedAddressConfig is true when addresses are available via DHCPv6. If
  230. // set, the OtherConfig flag is redundant.
  231. func (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool {
  232. return i.Flags&0x80 != 0
  233. }
  234. // OtherConfig is true when there is other configuration information available
  235. // via DHCPv6. For example, DNS-related information.
  236. func (i *ICMPv6RouterAdvertisement) OtherConfig() bool {
  237. return i.Flags&0x40 != 0
  238. }
  239. // LayerType returns LayerTypeICMPv6NeighborSolicitation.
  240. func (i *ICMPv6NeighborSolicitation) LayerType() gopacket.LayerType {
  241. return LayerTypeICMPv6NeighborSolicitation
  242. }
  243. // NextLayerType returns the layer type contained by this DecodingLayer.
  244. func (i *ICMPv6NeighborSolicitation) NextLayerType() gopacket.LayerType {
  245. return gopacket.LayerTypePayload
  246. }
  247. // DecodeFromBytes decodes the given bytes into this layer.
  248. func (i *ICMPv6NeighborSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  249. if len(data) < 20 {
  250. df.SetTruncated()
  251. return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor solicitation")
  252. }
  253. i.TargetAddress = net.IP(data[4:20])
  254. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  255. // truncate old options
  256. i.Options = i.Options[:0]
  257. return i.Options.DecodeFromBytes(data[20:], df)
  258. }
  259. // SerializeTo writes the serialized form of this layer into the
  260. // SerializationBuffer, implementing gopacket.SerializableLayer.
  261. // See the docs for gopacket.SerializableLayer for more info.
  262. func (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  263. if err := i.Options.SerializeTo(b, opts); err != nil {
  264. return err
  265. }
  266. buf, err := b.PrependBytes(20)
  267. if err != nil {
  268. return err
  269. }
  270. copy(buf, lotsOfZeros[:4])
  271. copy(buf[4:], i.TargetAddress)
  272. return nil
  273. }
  274. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  275. func (i *ICMPv6NeighborSolicitation) CanDecode() gopacket.LayerClass {
  276. return LayerTypeICMPv6NeighborSolicitation
  277. }
  278. // LayerType returns LayerTypeICMPv6NeighborAdvertisement.
  279. func (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType {
  280. return LayerTypeICMPv6NeighborAdvertisement
  281. }
  282. // NextLayerType returns the layer type contained by this DecodingLayer.
  283. func (i *ICMPv6NeighborAdvertisement) NextLayerType() gopacket.LayerType {
  284. return gopacket.LayerTypePayload
  285. }
  286. // DecodeFromBytes decodes the given bytes into this layer.
  287. func (i *ICMPv6NeighborAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  288. if len(data) < 20 {
  289. df.SetTruncated()
  290. return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor advertisement")
  291. }
  292. i.Flags = uint8(data[0])
  293. i.TargetAddress = net.IP(data[4:20])
  294. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  295. // truncate old options
  296. i.Options = i.Options[:0]
  297. return i.Options.DecodeFromBytes(data[20:], df)
  298. }
  299. // SerializeTo writes the serialized form of this layer into the
  300. // SerializationBuffer, implementing gopacket.SerializableLayer.
  301. // See the docs for gopacket.SerializableLayer for more info.
  302. func (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  303. if err := i.Options.SerializeTo(b, opts); err != nil {
  304. return err
  305. }
  306. buf, err := b.PrependBytes(20)
  307. if err != nil {
  308. return err
  309. }
  310. buf[0] = byte(i.Flags)
  311. copy(buf[1:], lotsOfZeros[:3])
  312. copy(buf[4:], i.TargetAddress)
  313. return nil
  314. }
  315. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  316. func (i *ICMPv6NeighborAdvertisement) CanDecode() gopacket.LayerClass {
  317. return LayerTypeICMPv6NeighborAdvertisement
  318. }
  319. // Router indicates whether the sender is a router or not.
  320. func (i *ICMPv6NeighborAdvertisement) Router() bool {
  321. return i.Flags&0x80 != 0
  322. }
  323. // Solicited indicates whether the advertisement was solicited or not.
  324. func (i *ICMPv6NeighborAdvertisement) Solicited() bool {
  325. return i.Flags&0x40 != 0
  326. }
  327. // Override indicates whether the advertisement should Override an existing
  328. // cache entry.
  329. func (i *ICMPv6NeighborAdvertisement) Override() bool {
  330. return i.Flags&0x20 != 0
  331. }
  332. // LayerType returns LayerTypeICMPv6Redirect.
  333. func (i *ICMPv6Redirect) LayerType() gopacket.LayerType {
  334. return LayerTypeICMPv6Redirect
  335. }
  336. // NextLayerType returns the layer type contained by this DecodingLayer.
  337. func (i *ICMPv6Redirect) NextLayerType() gopacket.LayerType {
  338. return gopacket.LayerTypePayload
  339. }
  340. // DecodeFromBytes decodes the given bytes into this layer.
  341. func (i *ICMPv6Redirect) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  342. if len(data) < 36 {
  343. df.SetTruncated()
  344. return errors.New("ICMP layer less then 36 bytes for ICMPv6 redirect")
  345. }
  346. i.TargetAddress = net.IP(data[4:20])
  347. i.DestinationAddress = net.IP(data[20:36])
  348. i.BaseLayer = BaseLayer{data, nil} // assume no payload
  349. // truncate old options
  350. i.Options = i.Options[:0]
  351. return i.Options.DecodeFromBytes(data[36:], df)
  352. }
  353. // SerializeTo writes the serialized form of this layer into the
  354. // SerializationBuffer, implementing gopacket.SerializableLayer.
  355. // See the docs for gopacket.SerializableLayer for more info.
  356. func (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  357. if err := i.Options.SerializeTo(b, opts); err != nil {
  358. return err
  359. }
  360. buf, err := b.PrependBytes(36)
  361. if err != nil {
  362. return err
  363. }
  364. copy(buf, lotsOfZeros[:4])
  365. copy(buf[4:], i.TargetAddress)
  366. copy(buf[20:], i.DestinationAddress)
  367. return nil
  368. }
  369. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  370. func (i *ICMPv6Redirect) CanDecode() gopacket.LayerClass {
  371. return LayerTypeICMPv6Redirect
  372. }
  373. func (i ICMPv6Option) String() string {
  374. hd := hex.EncodeToString(i.Data)
  375. if len(hd) > 0 {
  376. hd = " 0x" + hd
  377. }
  378. switch i.Type {
  379. case ICMPv6OptSourceAddress, ICMPv6OptTargetAddress:
  380. return fmt.Sprintf("ICMPv6Option(%s:%v)",
  381. i.Type,
  382. net.HardwareAddr(i.Data))
  383. case ICMPv6OptPrefixInfo:
  384. if len(i.Data) == 30 {
  385. prefixLen := uint8(i.Data[0])
  386. onLink := (i.Data[1]&0x80 != 0)
  387. autonomous := (i.Data[1]&0x40 != 0)
  388. validLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[2:6])) * time.Second
  389. preferredLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[6:10])) * time.Second
  390. prefix := net.IP(i.Data[14:])
  391. return fmt.Sprintf("ICMPv6Option(%s:%v/%v:%t:%t:%v:%v)",
  392. i.Type,
  393. prefix, prefixLen,
  394. onLink, autonomous,
  395. validLifetime, preferredLifetime)
  396. }
  397. case ICMPv6OptRedirectedHeader:
  398. // could invoke IP decoder on data... probably best not to
  399. break
  400. case ICMPv6OptMTU:
  401. if len(i.Data) == 6 {
  402. return fmt.Sprintf("ICMPv6Option(%s:%v)",
  403. i.Type,
  404. binary.BigEndian.Uint32(i.Data[2:]))
  405. }
  406. }
  407. return fmt.Sprintf("ICMPv6Option(%s:%s)", i.Type, hd)
  408. }
  409. // DecodeFromBytes decodes the given bytes into this layer.
  410. func (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  411. for len(data) > 0 {
  412. if len(data) < 2 {
  413. df.SetTruncated()
  414. return errors.New("ICMP layer less then 2 bytes for ICMPv6 message option")
  415. }
  416. // unit is 8 octets, convert to bytes
  417. length := int(data[1]) * 8
  418. if length == 0 {
  419. df.SetTruncated()
  420. return errors.New("ICMPv6 message option with length 0")
  421. }
  422. if len(data) < length {
  423. df.SetTruncated()
  424. return fmt.Errorf("ICMP layer only %v bytes for ICMPv6 message option with length %v", len(data), length)
  425. }
  426. o := ICMPv6Option{
  427. Type: ICMPv6Opt(data[0]),
  428. Data: data[2:length],
  429. }
  430. // chop off option we just consumed
  431. data = data[length:]
  432. *i = append(*i, o)
  433. }
  434. return nil
  435. }
  436. // SerializeTo writes the serialized form of this layer into the
  437. // SerializationBuffer, implementing gopacket.SerializableLayer.
  438. // See the docs for gopacket.SerializableLayer for more info.
  439. func (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  440. for _, opt := range []ICMPv6Option(*i) {
  441. length := len(opt.Data) + 2
  442. buf, err := b.PrependBytes(length)
  443. if err != nil {
  444. return err
  445. }
  446. buf[0] = byte(opt.Type)
  447. buf[1] = byte(length / 8)
  448. copy(buf[2:], opt.Data)
  449. }
  450. return nil
  451. }
  452. func decodeICMPv6Echo(data []byte, p gopacket.PacketBuilder) error {
  453. i := &ICMPv6Echo{}
  454. return decodingLayerDecoder(i, data, p)
  455. }
  456. func decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error {
  457. i := &ICMPv6RouterSolicitation{}
  458. return decodingLayerDecoder(i, data, p)
  459. }
  460. func decodeICMPv6RouterAdvertisement(data []byte, p gopacket.PacketBuilder) error {
  461. i := &ICMPv6RouterAdvertisement{}
  462. return decodingLayerDecoder(i, data, p)
  463. }
  464. func decodeICMPv6NeighborSolicitation(data []byte, p gopacket.PacketBuilder) error {
  465. i := &ICMPv6NeighborSolicitation{}
  466. return decodingLayerDecoder(i, data, p)
  467. }
  468. func decodeICMPv6NeighborAdvertisement(data []byte, p gopacket.PacketBuilder) error {
  469. i := &ICMPv6NeighborAdvertisement{}
  470. return decodingLayerDecoder(i, data, p)
  471. }
  472. func decodeICMPv6Redirect(data []byte, p gopacket.PacketBuilder) error {
  473. i := &ICMPv6Redirect{}
  474. return decodingLayerDecoder(i, data, p)
  475. }