decoder.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package packet
  2. import (
  3. "fmt"
  4. "github.com/google/gopacket"
  5. "github.com/google/gopacket/layers"
  6. "github.com/pkg/errors"
  7. "golang.org/x/net/icmp"
  8. )
  9. func FindProtocol(p []byte) (layers.IPProtocol, error) {
  10. version, err := FindIPVersion(p)
  11. if err != nil {
  12. return 0, err
  13. }
  14. switch version {
  15. case 4:
  16. if len(p) < ipv4MinHeaderLen {
  17. return 0, fmt.Errorf("IPv4 packet should have at least %d bytes, got %d bytes", ipv4MinHeaderLen, len(p))
  18. }
  19. // Protocol is in the 10th byte of IPv4 header
  20. return layers.IPProtocol(p[9]), nil
  21. case 6:
  22. if len(p) < ipv6HeaderLen {
  23. return 0, fmt.Errorf("IPv6 packet should have at least %d bytes, got %d bytes", ipv6HeaderLen, len(p))
  24. }
  25. // Next header is in the 7th byte of IPv6 header
  26. return layers.IPProtocol(p[6]), nil
  27. default:
  28. return 0, fmt.Errorf("unknow ip version %d", version)
  29. }
  30. }
  31. func FindIPVersion(p []byte) (uint8, error) {
  32. if len(p) == 0 {
  33. return 0, fmt.Errorf("packet length is 0")
  34. }
  35. return p[0] >> 4, nil
  36. }
  37. // IPDecoder decodes raw packets into IP. It can process packets sequentially without allocating
  38. // memory for the layers, so it cannot be called concurrently.
  39. type IPDecoder struct {
  40. ipv4 *layers.IPv4
  41. ipv6 *layers.IPv6
  42. layers uint8
  43. v4parser *gopacket.DecodingLayerParser
  44. v6parser *gopacket.DecodingLayerParser
  45. }
  46. func NewIPDecoder() *IPDecoder {
  47. var (
  48. ipv4 layers.IPv4
  49. ipv6 layers.IPv6
  50. )
  51. dlpv4 := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4)
  52. dlpv4.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))
  53. dlpv4.AddDecodingLayer(&ipv4)
  54. // Stop parsing when it encounter a layer that it doesn't have a parser
  55. dlpv4.IgnoreUnsupported = true
  56. dlpv6 := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv6)
  57. dlpv6.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))
  58. dlpv6.AddDecodingLayer(&ipv6)
  59. dlpv6.IgnoreUnsupported = true
  60. return &IPDecoder{
  61. ipv4: &ipv4,
  62. ipv6: &ipv6,
  63. layers: 1,
  64. v4parser: dlpv4,
  65. v6parser: dlpv6,
  66. }
  67. }
  68. func (pd *IPDecoder) Decode(packet RawPacket) (*IP, error) {
  69. // Should decode to IP layer
  70. decoded, err := pd.decodeByVersion(packet.Data)
  71. if err != nil {
  72. return nil, err
  73. }
  74. for _, layerType := range decoded {
  75. switch layerType {
  76. case layers.LayerTypeIPv4:
  77. return newIPv4(pd.ipv4)
  78. case layers.LayerTypeIPv6:
  79. return newIPv6(pd.ipv6)
  80. }
  81. }
  82. return nil, fmt.Errorf("no ip layer is decoded")
  83. }
  84. func (pd *IPDecoder) decodeByVersion(packet []byte) ([]gopacket.LayerType, error) {
  85. version, err := FindIPVersion(packet)
  86. if err != nil {
  87. return nil, err
  88. }
  89. decoded := make([]gopacket.LayerType, 0, pd.layers)
  90. switch version {
  91. case 4:
  92. err = pd.v4parser.DecodeLayers(packet, &decoded)
  93. case 6:
  94. err = pd.v6parser.DecodeLayers(packet, &decoded)
  95. default:
  96. err = fmt.Errorf("unknow ip version %d", version)
  97. }
  98. if err != nil {
  99. return nil, err
  100. }
  101. return decoded, nil
  102. }
  103. // ICMPDecoder decodes raw packets into IP and ICMP. It can process packets sequentially without allocating
  104. // memory for the layers, so it cannot be called concurrently.
  105. type ICMPDecoder struct {
  106. *IPDecoder
  107. icmpv4 *layers.ICMPv4
  108. icmpv6 *layers.ICMPv6
  109. }
  110. func NewICMPDecoder() *ICMPDecoder {
  111. ipDecoder := NewIPDecoder()
  112. var (
  113. icmpv4 layers.ICMPv4
  114. icmpv6 layers.ICMPv6
  115. )
  116. ipDecoder.layers++
  117. ipDecoder.v4parser.AddDecodingLayer(&icmpv4)
  118. ipDecoder.v6parser.AddDecodingLayer(&icmpv6)
  119. return &ICMPDecoder{
  120. IPDecoder: ipDecoder,
  121. icmpv4: &icmpv4,
  122. icmpv6: &icmpv6,
  123. }
  124. }
  125. func (pd *ICMPDecoder) Decode(packet RawPacket) (*ICMP, error) {
  126. // Should decode to IP and optionally ICMP layer
  127. decoded, err := pd.decodeByVersion(packet.Data)
  128. if err != nil {
  129. return nil, err
  130. }
  131. for _, layerType := range decoded {
  132. switch layerType {
  133. case layers.LayerTypeICMPv4:
  134. ipv4, err := newIPv4(pd.ipv4)
  135. if err != nil {
  136. return nil, err
  137. }
  138. msg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv4), append(pd.icmpv4.Contents, pd.icmpv4.Payload...))
  139. if err != nil {
  140. return nil, errors.Wrap(err, "failed to parse ICMPv4 message")
  141. }
  142. return &ICMP{
  143. IP: ipv4,
  144. Message: msg,
  145. }, nil
  146. case layers.LayerTypeICMPv6:
  147. ipv6, err := newIPv6(pd.ipv6)
  148. if err != nil {
  149. return nil, err
  150. }
  151. msg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv6), append(pd.icmpv6.Contents, pd.icmpv6.Payload...))
  152. if err != nil {
  153. return nil, errors.Wrap(err, "failed to parse ICMPv6")
  154. }
  155. return &ICMP{
  156. IP: ipv6,
  157. Message: msg,
  158. }, nil
  159. }
  160. }
  161. layers := make([]string, len(decoded))
  162. for i, l := range decoded {
  163. layers[i] = l.String()
  164. }
  165. return nil, fmt.Errorf("Expect to decode IP and ICMP layers, got %s", layers)
  166. }