github.com/gopacket/gopacket@v1.1.0/pcapgo/ngwrite_test.go (about)

     1  // Copyright 2018 The GoPacket Authors. 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 pcapgo
     8  
     9  import (
    10  	"bytes"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/gopacket/gopacket"
    15  	"github.com/gopacket/gopacket/layers"
    16  )
    17  
    18  func TestNgWriteSimple(t *testing.T) {
    19  	buffer := &bytes.Buffer{}
    20  
    21  	w, err := NewNgWriter(buffer, layers.LinkTypeEthernet)
    22  	if err != nil {
    23  		t.Fatal("Opening file failed with: ", err)
    24  	}
    25  	ci := gopacket.CaptureInfo{
    26  		Timestamp:      time.Unix(0, 0).UTC(),
    27  		Length:         len(ngPacketSource[0]),
    28  		CaptureLength:  len(ngPacketSource[0]),
    29  		InterfaceIndex: 0,
    30  	}
    31  	err = w.WritePacket(ci, ngPacketSource[0])
    32  	if err != nil {
    33  		t.Fatal("Couldn't write packet", err)
    34  	}
    35  	err = w.Flush()
    36  	if err != nil {
    37  		t.Fatal("Couldn't flush buffer", err)
    38  	}
    39  
    40  	interf := DefaultNgInterface
    41  	interf.LinkType = layers.LinkTypeEthernet
    42  
    43  	test := ngFileReadTest{
    44  		testContents: bytes.NewReader(buffer.Bytes()),
    45  		linkType:     layers.LinkTypeEthernet,
    46  		sections: []ngFileReadTestSection{
    47  			{
    48  				sectionInfo: DefaultNgWriterOptions.SectionInfo,
    49  				ifaces: []NgInterface{
    50  					interf,
    51  				},
    52  			},
    53  		},
    54  		packets: []ngFileReadTestPacket{
    55  			{
    56  				data: ngPacketSource[0],
    57  				ci:   ci,
    58  			},
    59  		},
    60  	}
    61  
    62  	ngRunFileReadTest(test, "", false, t)
    63  }
    64  
    65  func TestNgWriteComplex(t *testing.T) {
    66  	test := ngFileReadTest{
    67  		linkType: layers.LinkTypeEthernet,
    68  		sections: []ngFileReadTestSection{
    69  			{
    70  				sectionInfo: NgSectionInfo{
    71  					Comment: "A test",
    72  				},
    73  				ifaces: []NgInterface{
    74  					{
    75  						Name:                "in0",
    76  						Comment:             "test0",
    77  						Description:         "some test interface",
    78  						LinkType:            layers.LinkTypeEthernet,
    79  						TimestampResolution: 3,
    80  						Statistics: NgInterfaceStatistics{
    81  							LastUpdate:      time.Unix(1519128000, 195312500).UTC(),
    82  							StartTime:       time.Unix(1519128000-100, 195312500).UTC(),
    83  							EndTime:         time.Unix(1519128000, 195312500).UTC(),
    84  							PacketsReceived: 100,
    85  							PacketsDropped:  1,
    86  						},
    87  					},
    88  					{
    89  						Name:            "null0",
    90  						Description:     "some test interface",
    91  						Filter:          "none",
    92  						OS:              "not needed",
    93  						LinkType:        layers.LinkTypeEthernet,
    94  						TimestampOffset: 100,
    95  						Statistics: NgInterfaceStatistics{
    96  							LastUpdate: time.Unix(1519128000, 195312500).UTC(),
    97  						},
    98  					},
    99  				},
   100  			},
   101  		},
   102  		packets: []ngFileReadTestPacket{
   103  			{
   104  				data: ngPacketSource[0],
   105  				ci: gopacket.CaptureInfo{
   106  					Timestamp:      time.Unix(1519128000-900, 195312500).UTC(),
   107  					Length:         len(ngPacketSource[0]),
   108  					CaptureLength:  len(ngPacketSource[0]),
   109  					InterfaceIndex: 0,
   110  				},
   111  			},
   112  			{
   113  				data: ngPacketSource[4],
   114  				ci: gopacket.CaptureInfo{
   115  					Timestamp:      time.Unix(1519128000-800, 195312500).UTC(),
   116  					Length:         len(ngPacketSource[4]),
   117  					CaptureLength:  len(ngPacketSource[4]),
   118  					InterfaceIndex: 1,
   119  				},
   120  			},
   121  			{
   122  				data: ngPacketSource[1],
   123  				ci: gopacket.CaptureInfo{
   124  					Timestamp:      time.Unix(1519128000-500, 195312500).UTC(),
   125  					Length:         len(ngPacketSource[1]),
   126  					CaptureLength:  len(ngPacketSource[1]),
   127  					InterfaceIndex: 0,
   128  				},
   129  			},
   130  			{
   131  				data: ngPacketSource[2][:96],
   132  				ci: gopacket.CaptureInfo{
   133  					Timestamp:      time.Unix(1519128000-300, 195312500).UTC(),
   134  					Length:         len(ngPacketSource[2]),
   135  					CaptureLength:  96,
   136  					InterfaceIndex: 0,
   137  				},
   138  			},
   139  			{
   140  				data: ngPacketSource[3],
   141  				ci: gopacket.CaptureInfo{
   142  					Timestamp:      time.Unix(1519128000-200, 195312500).UTC(),
   143  					Length:         len(ngPacketSource[3]),
   144  					CaptureLength:  len(ngPacketSource[3]),
   145  					InterfaceIndex: 0,
   146  				},
   147  			},
   148  		},
   149  	}
   150  
   151  	buffer := &bytes.Buffer{}
   152  
   153  	options := NgWriterOptions{
   154  		SectionInfo: test.sections[0].sectionInfo,
   155  	}
   156  
   157  	w, err := NewNgWriterInterface(buffer, test.sections[0].ifaces[0], options)
   158  	if err != nil {
   159  		t.Fatal("Opening file failed with: ", err)
   160  	}
   161  
   162  	packets := test.packets
   163  	err = w.WritePacket(packets[0].ci, packets[0].data)
   164  	if err != nil {
   165  		t.Fatal("Couldn't write packet", err)
   166  	}
   167  	id, err := w.AddInterface(test.sections[0].ifaces[1])
   168  	if err != nil {
   169  		t.Fatal("Couldn't add interface", err)
   170  	}
   171  	if id != 1 {
   172  		t.Fatalf("Expected interface id 1, but got %d", id)
   173  	}
   174  	err = w.WritePacket(packets[1].ci, packets[1].data)
   175  	if err != nil {
   176  		t.Fatal("Couldn't write packet", err)
   177  	}
   178  	err = w.WriteInterfaceStats(1, test.sections[0].ifaces[1].Statistics)
   179  	if err != nil {
   180  		t.Fatal("Couldn't write interface stats", err)
   181  	}
   182  	err = w.WritePacket(packets[2].ci, packets[2].data)
   183  	if err != nil {
   184  		t.Fatal("Couldn't write packet", err)
   185  	}
   186  	err = w.WritePacket(packets[3].ci, packets[3].data)
   187  	if err != nil {
   188  		t.Fatal("Couldn't write packet", err)
   189  	}
   190  	err = w.WritePacket(packets[4].ci, packets[4].data)
   191  	if err != nil {
   192  		t.Fatal("Couldn't write packet", err)
   193  	}
   194  	err = w.WriteInterfaceStats(0, test.sections[0].ifaces[0].Statistics)
   195  	if err != nil {
   196  		t.Fatal("Couldn't write interface stats", err)
   197  	}
   198  
   199  	err = w.Flush()
   200  	if err != nil {
   201  		t.Fatal("Couldn't flush buffer", err)
   202  	}
   203  
   204  	// writer fixes resolution to 9
   205  	test.sections[0].ifaces[0].TimestampResolution = 9
   206  	test.sections[0].ifaces[1].TimestampResolution = 9
   207  
   208  	// compensate for offset on interface 1
   209  	test.sections[0].ifaces[1].Statistics.LastUpdate = test.sections[0].ifaces[1].Statistics.LastUpdate.Add(100 * time.Second)
   210  	test.packets[1].ci.Timestamp = test.packets[1].ci.Timestamp.Add(100 * time.Second)
   211  
   212  	test.testContents = bytes.NewReader(buffer.Bytes())
   213  
   214  	ngRunFileReadTest(test, "", false, t)
   215  }
   216  
   217  type ngDevNull struct{}
   218  
   219  func (w *ngDevNull) Write(p []byte) (n int, err error) {
   220  	return len(p), nil
   221  }
   222  
   223  func BenchmarkNgWritePacket(b *testing.B) {
   224  	ci := gopacket.CaptureInfo{
   225  		Timestamp:     time.Unix(0x01020304, 0xAA*1000),
   226  		Length:        0xABCD,
   227  		CaptureLength: 10,
   228  	}
   229  	data := []byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
   230  	w, err := NewNgWriter(&ngDevNull{}, layers.LinkTypeEthernet)
   231  	if err != nil {
   232  		b.Fatal("Failed creating writer:", err)
   233  	}
   234  	b.ResetTimer()
   235  
   236  	for i := 0; i < b.N; i++ {
   237  		w.WritePacket(ci, data)
   238  	}
   239  }