io.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package pcap
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "io"
  6. "time"
  7. )
  8. // FileHeader is the parsed header of a pcap file.
  9. // http://wiki.wireshark.org/Development/LibpcapFileFormat
  10. type FileHeader struct {
  11. MagicNumber uint32
  12. VersionMajor uint16
  13. VersionMinor uint16
  14. TimeZone int32
  15. SigFigs uint32
  16. SnapLen uint32
  17. Network uint32
  18. }
  19. type PacketTime struct {
  20. Sec int32
  21. Usec int32
  22. }
  23. // Convert the PacketTime to a go Time struct.
  24. func (p *PacketTime) Time() time.Time {
  25. return time.Unix(int64(p.Sec), int64(p.Usec)*1000)
  26. }
  27. // Packet is a single packet parsed from a pcap file.
  28. //
  29. // Convenient access to IP, TCP, and UDP headers is provided after Decode()
  30. // is called if the packet is of the appropriate type.
  31. type Packet struct {
  32. Time time.Time // packet send/receive time
  33. Caplen uint32 // bytes stored in the file (caplen <= len)
  34. Len uint32 // bytes sent/received
  35. Data []byte // packet data
  36. Type int // protocol type, see LINKTYPE_*
  37. DestMac uint64
  38. SrcMac uint64
  39. Headers []interface{} // decoded headers, in order
  40. Payload []byte // remaining non-header bytes
  41. IP *Iphdr // IP header (for IP packets, after decoding)
  42. TCP *Tcphdr // TCP header (for TCP packets, after decoding)
  43. UDP *Udphdr // UDP header (for UDP packets after decoding)
  44. }
  45. // Reader parses pcap files.
  46. type Reader struct {
  47. flip bool
  48. buf io.Reader
  49. err error
  50. fourBytes []byte
  51. twoBytes []byte
  52. sixteenBytes []byte
  53. Header FileHeader
  54. }
  55. // NewReader reads pcap data from an io.Reader.
  56. func NewReader(reader io.Reader) (*Reader, error) {
  57. r := &Reader{
  58. buf: reader,
  59. fourBytes: make([]byte, 4),
  60. twoBytes: make([]byte, 2),
  61. sixteenBytes: make([]byte, 16),
  62. }
  63. switch magic := r.readUint32(); magic {
  64. case 0xa1b2c3d4:
  65. r.flip = false
  66. case 0xd4c3b2a1:
  67. r.flip = true
  68. default:
  69. return nil, fmt.Errorf("pcap: bad magic number: %0x", magic)
  70. }
  71. r.Header = FileHeader{
  72. MagicNumber: 0xa1b2c3d4,
  73. VersionMajor: r.readUint16(),
  74. VersionMinor: r.readUint16(),
  75. TimeZone: r.readInt32(),
  76. SigFigs: r.readUint32(),
  77. SnapLen: r.readUint32(),
  78. Network: r.readUint32(),
  79. }
  80. return r, nil
  81. }
  82. // Next returns the next packet or nil if no more packets can be read.
  83. func (r *Reader) Next() *Packet {
  84. d := r.sixteenBytes
  85. r.err = r.read(d)
  86. if r.err != nil {
  87. return nil
  88. }
  89. timeSec := asUint32(d[0:4], r.flip)
  90. timeUsec := asUint32(d[4:8], r.flip)
  91. capLen := asUint32(d[8:12], r.flip)
  92. origLen := asUint32(d[12:16], r.flip)
  93. data := make([]byte, capLen)
  94. if r.err = r.read(data); r.err != nil {
  95. return nil
  96. }
  97. return &Packet{
  98. Time: time.Unix(int64(timeSec), int64(timeUsec)),
  99. Caplen: capLen,
  100. Len: origLen,
  101. Data: data,
  102. }
  103. }
  104. func (r *Reader) read(data []byte) error {
  105. var err error
  106. n, err := r.buf.Read(data)
  107. for err == nil && n != len(data) {
  108. var chunk int
  109. chunk, err = r.buf.Read(data[n:])
  110. n += chunk
  111. }
  112. if len(data) == n {
  113. return nil
  114. }
  115. return err
  116. }
  117. func (r *Reader) readUint32() uint32 {
  118. data := r.fourBytes
  119. if r.err = r.read(data); r.err != nil {
  120. return 0
  121. }
  122. return asUint32(data, r.flip)
  123. }
  124. func (r *Reader) readInt32() int32 {
  125. data := r.fourBytes
  126. if r.err = r.read(data); r.err != nil {
  127. return 0
  128. }
  129. return int32(asUint32(data, r.flip))
  130. }
  131. func (r *Reader) readUint16() uint16 {
  132. data := r.twoBytes
  133. if r.err = r.read(data); r.err != nil {
  134. return 0
  135. }
  136. return asUint16(data, r.flip)
  137. }
  138. // Writer writes a pcap file.
  139. type Writer struct {
  140. writer io.Writer
  141. buf []byte
  142. }
  143. // NewWriter creates a Writer that stores output in an io.Writer.
  144. // The FileHeader is written immediately.
  145. func NewWriter(writer io.Writer, header *FileHeader) (*Writer, error) {
  146. w := &Writer{
  147. writer: writer,
  148. buf: make([]byte, 24),
  149. }
  150. binary.LittleEndian.PutUint32(w.buf, header.MagicNumber)
  151. binary.LittleEndian.PutUint16(w.buf[4:], header.VersionMajor)
  152. binary.LittleEndian.PutUint16(w.buf[6:], header.VersionMinor)
  153. binary.LittleEndian.PutUint32(w.buf[8:], uint32(header.TimeZone))
  154. binary.LittleEndian.PutUint32(w.buf[12:], header.SigFigs)
  155. binary.LittleEndian.PutUint32(w.buf[16:], header.SnapLen)
  156. binary.LittleEndian.PutUint32(w.buf[20:], header.Network)
  157. if _, err := writer.Write(w.buf); err != nil {
  158. return nil, err
  159. }
  160. return w, nil
  161. }
  162. // Writer writes a packet to the underlying writer.
  163. func (w *Writer) Write(pkt *Packet) error {
  164. binary.LittleEndian.PutUint32(w.buf, uint32(pkt.Time.Unix()))
  165. binary.LittleEndian.PutUint32(w.buf[4:], uint32(pkt.Time.Nanosecond()))
  166. binary.LittleEndian.PutUint32(w.buf[8:], uint32(pkt.Time.Unix()))
  167. binary.LittleEndian.PutUint32(w.buf[12:], pkt.Len)
  168. if _, err := w.writer.Write(w.buf[:16]); err != nil {
  169. return err
  170. }
  171. _, err := w.writer.Write(pkt.Data)
  172. return err
  173. }
  174. func asUint32(data []byte, flip bool) uint32 {
  175. if flip {
  176. return binary.BigEndian.Uint32(data)
  177. }
  178. return binary.LittleEndian.Uint32(data)
  179. }
  180. func asUint16(data []byte, flip bool) uint16 {
  181. if flip {
  182. return binary.BigEndian.Uint16(data)
  183. }
  184. return binary.LittleEndian.Uint16(data)
  185. }