doc.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. /*
  7. Package gopacket provides packet decoding for the Go language.
  8. gopacket contains many sub-packages with additional functionality you may find
  9. useful, including:
  10. * layers: You'll probably use this every time. This contains of the logic
  11. built into gopacket for decoding packet protocols. Note that all example
  12. code below assumes that you have imported both gopacket and
  13. gopacket/layers.
  14. * pcap: C bindings to use libpcap to read packets off the wire.
  15. * pfring: C bindings to use PF_RING to read packets off the wire.
  16. * afpacket: C bindings for Linux's AF_PACKET to read packets off the wire.
  17. * tcpassembly: TCP stream reassembly
  18. Also, if you're looking to dive right into code, see the examples subdirectory
  19. for numerous simple binaries built using gopacket libraries.
  20. Minimum go version required is 1.5.
  21. Basic Usage
  22. gopacket takes in packet data as a []byte and decodes it into a packet with
  23. a non-zero number of "layers". Each layer corresponds to a protocol
  24. within the bytes. Once a packet has been decoded, the layers of the packet
  25. can be requested from the packet.
  26. // Decode a packet
  27. packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)
  28. // Get the TCP layer from this packet
  29. if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
  30. fmt.Println("This is a TCP packet!")
  31. // Get actual TCP data from this layer
  32. tcp, _ := tcpLayer.(*layers.TCP)
  33. fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
  34. }
  35. // Iterate over all layers, printing out each layer type
  36. for _, layer := range packet.Layers() {
  37. fmt.Println("PACKET LAYER:", layer.LayerType())
  38. }
  39. Packets can be decoded from a number of starting points. Many of our base
  40. types implement Decoder, which allow us to decode packets for which
  41. we don't have full data.
  42. // Decode an ethernet packet
  43. ethP := gopacket.NewPacket(p1, layers.LayerTypeEthernet, gopacket.Default)
  44. // Decode an IPv6 header and everything it contains
  45. ipP := gopacket.NewPacket(p2, layers.LayerTypeIPv6, gopacket.Default)
  46. // Decode a TCP header and its payload
  47. tcpP := gopacket.NewPacket(p3, layers.LayerTypeTCP, gopacket.Default)
  48. Reading Packets From A Source
  49. Most of the time, you won't just have a []byte of packet data lying around.
  50. Instead, you'll want to read packets in from somewhere (file, interface, etc)
  51. and process them. To do that, you'll want to build a PacketSource.
  52. First, you'll need to construct an object that implements the PacketDataSource
  53. interface. There are implementations of this interface bundled with gopacket
  54. in the gopacket/pcap and gopacket/pfring subpackages... see their documentation
  55. for more information on their usage. Once you have a PacketDataSource, you can
  56. pass it into NewPacketSource, along with a Decoder of your choice, to create
  57. a PacketSource.
  58. Once you have a PacketSource, you can read packets from it in multiple ways.
  59. See the docs for PacketSource for more details. The easiest method is the
  60. Packets function, which returns a channel, then asynchronously writes new
  61. packets into that channel, closing the channel if the packetSource hits an
  62. end-of-file.
  63. packetSource := ... // construct using pcap or pfring
  64. for packet := range packetSource.Packets() {
  65. handlePacket(packet) // do something with each packet
  66. }
  67. You can change the decoding options of the packetSource by setting fields in
  68. packetSource.DecodeOptions... see the following sections for more details.
  69. Lazy Decoding
  70. gopacket optionally decodes packet data lazily, meaning it
  71. only decodes a packet layer when it needs to handle a function call.
  72. // Create a packet, but don't actually decode anything yet
  73. packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
  74. // Now, decode the packet up to the first IPv4 layer found but no further.
  75. // If no IPv4 layer was found, the whole packet will be decoded looking for
  76. // it.
  77. ip4 := packet.Layer(layers.LayerTypeIPv4)
  78. // Decode all layers and return them. The layers up to the first IPv4 layer
  79. // are already decoded, and will not require decoding a second time.
  80. layers := packet.Layers()
  81. Lazily-decoded packets are not concurrency-safe. Since layers have not all been
  82. decoded, each call to Layer() or Layers() has the potential to mutate the packet
  83. in order to decode the next layer. If a packet is used
  84. in multiple goroutines concurrently, don't use gopacket.Lazy. Then gopacket
  85. will decode the packet fully, and all future function calls won't mutate the
  86. object.
  87. NoCopy Decoding
  88. By default, gopacket will copy the slice passed to NewPacket and store the
  89. copy within the packet, so future mutations to the bytes underlying the slice
  90. don't affect the packet and its layers. If you can guarantee that the
  91. underlying slice bytes won't be changed, you can use NoCopy to tell
  92. gopacket.NewPacket, and it'll use the passed-in slice itself.
  93. // This channel returns new byte slices, each of which points to a new
  94. // memory location that's guaranteed immutable for the duration of the
  95. // packet.
  96. for data := range myByteSliceChannel {
  97. p := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy)
  98. doSomethingWithPacket(p)
  99. }
  100. The fastest method of decoding is to use both Lazy and NoCopy, but note from
  101. the many caveats above that for some implementations either or both may be
  102. dangerous.
  103. Pointers To Known Layers
  104. During decoding, certain layers are stored in the packet as well-known
  105. layer types. For example, IPv4 and IPv6 are both considered NetworkLayer
  106. layers, while TCP and UDP are both TransportLayer layers. We support 4
  107. layers, corresponding to the 4 layers of the TCP/IP layering scheme (roughly
  108. anagalous to layers 2, 3, 4, and 7 of the OSI model). To access these,
  109. you can use the packet.LinkLayer, packet.NetworkLayer,
  110. packet.TransportLayer, and packet.ApplicationLayer functions. Each of
  111. these functions returns a corresponding interface
  112. (gopacket.{Link,Network,Transport,Application}Layer). The first three
  113. provide methods for getting src/dst addresses for that particular layer,
  114. while the final layer provides a Payload function to get payload data.
  115. This is helpful, for example, to get payloads for all packets regardless
  116. of their underlying data type:
  117. // Get packets from some source
  118. for packet := range someSource {
  119. if app := packet.ApplicationLayer(); app != nil {
  120. if strings.Contains(string(app.Payload()), "magic string") {
  121. fmt.Println("Found magic string in a packet!")
  122. }
  123. }
  124. }
  125. A particularly useful layer is ErrorLayer, which is set whenever there's
  126. an error parsing part of the packet.
  127. packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)
  128. if err := packet.ErrorLayer(); err != nil {
  129. fmt.Println("Error decoding some part of the packet:", err)
  130. }
  131. Note that we don't return an error from NewPacket because we may have decoded
  132. a number of layers successfully before running into our erroneous layer. You
  133. may still be able to get your Ethernet and IPv4 layers correctly, even if
  134. your TCP layer is malformed.
  135. Flow And Endpoint
  136. gopacket has two useful objects, Flow and Endpoint, for communicating in a protocol
  137. independent manner the fact that a packet is coming from A and going to B.
  138. The general layer types LinkLayer, NetworkLayer, and TransportLayer all provide
  139. methods for extracting their flow information, without worrying about the type
  140. of the underlying Layer.
  141. A Flow is a simple object made up of a set of two Endpoints, one source and one
  142. destination. It details the sender and receiver of the Layer of the Packet.
  143. An Endpoint is a hashable representation of a source or destination. For
  144. example, for LayerTypeIPv4, an Endpoint contains the IP address bytes for a v4
  145. IP packet. A Flow can be broken into Endpoints, and Endpoints can be combined
  146. into Flows:
  147. packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
  148. netFlow := packet.NetworkLayer().NetworkFlow()
  149. src, dst := netFlow.Endpoints()
  150. reverseFlow := gopacket.NewFlow(dst, src)
  151. Both Endpoint and Flow objects can be used as map keys, and the equality
  152. operator can compare them, so you can easily group together all packets
  153. based on endpoint criteria:
  154. flows := map[gopacket.Endpoint]chan gopacket.Packet
  155. packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
  156. // Send all TCP packets to channels based on their destination port.
  157. if tcp := packet.Layer(layers.LayerTypeTCP); tcp != nil {
  158. flows[tcp.TransportFlow().Dst()] <- packet
  159. }
  160. // Look for all packets with the same source and destination network address
  161. if net := packet.NetworkLayer(); net != nil {
  162. src, dst := net.NetworkFlow().Endpoints()
  163. if src == dst {
  164. fmt.Println("Fishy packet has same network source and dst: %s", src)
  165. }
  166. }
  167. // Find all packets coming from UDP port 1000 to UDP port 500
  168. interestingFlow := gopacket.NewFlow(layers.NewUDPPortEndpoint(1000), layers.NewUDPPortEndpoint(500))
  169. if t := packet.NetworkLayer(); t != nil && t.TransportFlow() == interestingFlow {
  170. fmt.Println("Found that UDP flow I was looking for!")
  171. }
  172. For load-balancing purposes, both Flow and Endpoint have FastHash() functions,
  173. which provide quick, non-cryptographic hashes of their contents. Of particular
  174. importance is the fact that Flow FastHash() is symmetric: A->B will have the same
  175. hash as B->A. An example usage could be:
  176. channels := [8]chan gopacket.Packet
  177. for i := 0; i < 8; i++ {
  178. channels[i] = make(chan gopacket.Packet)
  179. go packetHandler(channels[i])
  180. }
  181. for packet := range getPackets() {
  182. if net := packet.NetworkLayer(); net != nil {
  183. channels[int(net.NetworkFlow().FastHash()) & 0x7] <- packet
  184. }
  185. }
  186. This allows us to split up a packet stream while still making sure that each
  187. stream sees all packets for a flow (and its bidirectional opposite).
  188. Implementing Your Own Decoder
  189. If your network has some strange encapsulation, you can implement your own
  190. decoder. In this example, we handle Ethernet packets which are encapsulated
  191. in a 4-byte header.
  192. // Create a layer type, should be unique and high, so it doesn't conflict,
  193. // giving it a name and a decoder to use.
  194. var MyLayerType = gopacket.RegisterLayerType(12345, gopacket.LayerTypeMetadata{Name: "MyLayerType", Decoder: gopacket.DecodeFunc(decodeMyLayer)})
  195. // Implement my layer
  196. type MyLayer struct {
  197. StrangeHeader []byte
  198. payload []byte
  199. }
  200. func (m MyLayer) LayerType() gopacket.LayerType { return MyLayerType }
  201. func (m MyLayer) LayerContents() []byte { return m.StrangeHeader }
  202. func (m MyLayer) LayerPayload() []byte { return m.payload }
  203. // Now implement a decoder... this one strips off the first 4 bytes of the
  204. // packet.
  205. func decodeMyLayer(data []byte, p gopacket.PacketBuilder) error {
  206. // Create my layer
  207. p.AddLayer(&MyLayer{data[:4], data[4:]})
  208. // Determine how to handle the rest of the packet
  209. return p.NextDecoder(layers.LayerTypeEthernet)
  210. }
  211. // Finally, decode your packets:
  212. p := gopacket.NewPacket(data, MyLayerType, gopacket.Lazy)
  213. See the docs for Decoder and PacketBuilder for more details on how coding
  214. decoders works, or look at RegisterLayerType and RegisterEndpointType to see how
  215. to add layer/endpoint types to gopacket.
  216. Fast Decoding With DecodingLayerParser
  217. TLDR: DecodingLayerParser takes about 10% of the time as NewPacket to decode
  218. packet data, but only for known packet stacks.
  219. Basic decoding using gopacket.NewPacket or PacketSource.Packets is somewhat slow
  220. due to its need to allocate a new packet and every respective layer. It's very
  221. versatile and can handle all known layer types, but sometimes you really only
  222. care about a specific set of layers regardless, so that versatility is wasted.
  223. DecodingLayerParser avoids memory allocation altogether by decoding packet
  224. layers directly into preallocated objects, which you can then reference to get
  225. the packet's information. A quick example:
  226. func main() {
  227. var eth layers.Ethernet
  228. var ip4 layers.IPv4
  229. var ip6 layers.IPv6
  230. var tcp layers.TCP
  231. parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &ip6, &tcp)
  232. decoded := []gopacket.LayerType{}
  233. for packetData := range somehowGetPacketData() {
  234. if err := parser.DecodeLayers(packetData, &decoded); err != nil {
  235. fmt.Fprintf(os.Stderr, "Could not decode layers: %v\n", err)
  236. continue
  237. }
  238. for _, layerType := range decoded {
  239. switch layerType {
  240. case layers.LayerTypeIPv6:
  241. fmt.Println(" IP6 ", ip6.SrcIP, ip6.DstIP)
  242. case layers.LayerTypeIPv4:
  243. fmt.Println(" IP4 ", ip4.SrcIP, ip4.DstIP)
  244. }
  245. }
  246. }
  247. }
  248. The important thing to note here is that the parser is modifying the passed in
  249. layers (eth, ip4, ip6, tcp) instead of allocating new ones, thus greatly
  250. speeding up the decoding process. It's even branching based on layer type...
  251. it'll handle an (eth, ip4, tcp) or (eth, ip6, tcp) stack. However, it won't
  252. handle any other type... since no other decoders were passed in, an (eth, ip4,
  253. udp) stack will stop decoding after ip4, and only pass back [LayerTypeEthernet,
  254. LayerTypeIPv4] through the 'decoded' slice (along with an error saying it can't
  255. decode a UDP packet).
  256. Unfortunately, not all layers can be used by DecodingLayerParser... only those
  257. implementing the DecodingLayer interface are usable. Also, it's possible to
  258. create DecodingLayers that are not themselves Layers... see
  259. layers.IPv6ExtensionSkipper for an example of this.
  260. Creating Packet Data
  261. As well as offering the ability to decode packet data, gopacket will allow you
  262. to create packets from scratch, as well. A number of gopacket layers implement
  263. the SerializableLayer interface; these layers can be serialized to a []byte in
  264. the following manner:
  265. ip := &layers.IPv4{
  266. SrcIP: net.IP{1, 2, 3, 4},
  267. DstIP: net.IP{5, 6, 7, 8},
  268. // etc...
  269. }
  270. buf := gopacket.NewSerializeBuffer()
  271. opts := gopacket.SerializeOptions{} // See SerializeOptions for more details.
  272. err := ip.SerializeTo(buf, opts)
  273. if err != nil { panic(err) }
  274. fmt.Println(buf.Bytes()) // prints out a byte slice containing the serialized IPv4 layer.
  275. SerializeTo PREPENDS the given layer onto the SerializeBuffer, and they treat
  276. the current buffer's Bytes() slice as the payload of the serializing layer.
  277. Therefore, you can serialize an entire packet by serializing a set of layers in
  278. reverse order (Payload, then TCP, then IP, then Ethernet, for example). The
  279. SerializeBuffer's SerializeLayers function is a helper that does exactly that.
  280. To generate a (empty and useless, because no fields are set)
  281. Ethernet(IPv4(TCP(Payload))) packet, for example, you can run:
  282. buf := gopacket.NewSerializeBuffer()
  283. opts := gopacket.SerializeOptions{}
  284. gopacket.SerializeLayers(buf, opts,
  285. &layers.Ethernet{},
  286. &layers.IPv4{},
  287. &layers.TCP{},
  288. gopacket.Payload([]byte{1, 2, 3, 4}))
  289. packetData := buf.Bytes()
  290. A Final Note
  291. If you use gopacket, you'll almost definitely want to make sure gopacket/layers
  292. is imported, since when imported it sets all the LayerType variables and fills
  293. in a lot of interesting variables/maps (DecodersByLayerName, etc). Therefore,
  294. it's recommended that even if you don't use any layers functions directly, you still import with:
  295. import (
  296. _ "github.com/google/gopacket/layers"
  297. )
  298. */
  299. package gopacket