@@ -46,13 +46,19 @@ type Writer struct {
4646 packetNum uint64
4747}
4848
49+ // NewWriter creates a new mshark Writer.
50+ //
51+ // If the io.Writer is nil, the Writer will write to stdout.
4952func NewWriter (w io.Writer ) * Writer {
5053 if w == nil {
5154 w = os .Stdout
5255 }
5356 return & Writer {w : w }
5457}
5558
59+ // WritePacket writes a packet to the writer, along with its timestamp.
60+ //
61+ // Timestamps are to be generated by the calling code.
5662func (mw * Writer ) WritePacket (timestamp time.Time , data []byte ) error {
5763 mw .packetNum ++
5864 fmt .Fprintf (mw .w , "- Packet: %d Timestamp: %s\n " , mw .packetNum , timestamp .Format ("2006-01-02T15:04:05-0700" ))
@@ -115,6 +121,19 @@ func (mw *Writer) WritePacket(timestamp time.Time, data []byte) error {
115121 return nil
116122}
117123
124+ // WriteHeader writes a header to the writer.
125+ //
126+ // The header contains metadata about the capture, such as the interface name,
127+ // snapshot length, promiscuous mode, timeout, number of packets, and BPF filter.
128+ //
129+ // The header is written in the following format:
130+ //
131+ // - Interface: eth0
132+ // - Snapshot Length: 65535
133+ // - Promiscuous Mode: true
134+ // - Timeout: 5s
135+ // - Number of Packets: 0
136+ // - BPF Filter: "ip proto tcp"
118137func (mw * Writer ) WriteHeader (c * Config , in * net.Interface , snaplen int ) error {
119138 _ , err := fmt .Fprintf (mw .w , `- Interface: %s
120139- Snapshot Length: %d
@@ -134,6 +153,31 @@ func (mw *Writer) WriteHeader(c *Config, in *net.Interface, snaplen int) error {
134153 return err
135154}
136155
156+ // InterfaceByName returns the interface specified by name.
157+ func InterfaceByName (name string ) (* net.Interface , error ) {
158+ var (
159+ in * net.Interface
160+ err error
161+ )
162+ if name == "any" {
163+ in = & net.Interface {Index : 0 , Name : "any" }
164+ } else {
165+ in , err = net .InterfaceByName (name )
166+ if err != nil {
167+ return nil , fmt .Errorf ("unknown interface %s: %v" , name , err )
168+ }
169+ ok := true &&
170+ // Look for an Ethernet interface.
171+ len (in .HardwareAddr ) == 6 &&
172+ // Look for up, multicast, broadcast.
173+ in .Flags & (net .FlagUp | net .FlagMulticast | net .FlagBroadcast ) != 0
174+ if ! ok {
175+ return nil , fmt .Errorf ("interface %s is not up" , name )
176+ }
177+ }
178+ return in , nil
179+ }
180+
137181func OpenLive (conf * Config ) error {
138182
139183 packetcfg := packet.Config {}
@@ -153,26 +197,10 @@ func OpenLive(conf *Config) error {
153197 packetcfg .Filter = raw
154198 }
155199
156- var (
157- in * net.Interface
158- err error
159- )
160- iface := conf .Iface
161- if iface == "any" {
162- in = & net.Interface {Index : 0 , Name : "any" }
163- } else {
164- in , err = net .InterfaceByName (iface )
165- if err != nil {
166- return fmt .Errorf ("unknown interface %s: %v" , iface , err )
167- }
168- ok := true &&
169- // Look for an Ethernet interface.
170- len (in .HardwareAddr ) == 6 &&
171- // Look for up, multicast, broadcast.
172- in .Flags & (net .FlagUp | net .FlagMulticast | net .FlagBroadcast ) != 0
173- if ! ok {
174- return fmt .Errorf ("interface %s is not up" , iface )
175- }
200+ // getting interface
201+ in , err := InterfaceByName (conf .Iface )
202+ if err != nil {
203+ return err
176204 }
177205
178206 // opening connection
@@ -186,14 +214,14 @@ func OpenLive(conf *Config) error {
186214
187215 // setting promisc mode
188216 if in .Name != "any" {
189- if err = c .SetPromiscuous (conf .Promisc ); err != nil {
217+ if err : = c .SetPromiscuous (conf .Promisc ); err != nil {
190218 return fmt .Errorf ("unable to set promiscuous mode: %v" , err )
191219 }
192220 }
193221
194222 // timeout
195223 if conf .Timeout > 0 {
196- if err = c .SetDeadline (time .Now ().Add (conf .Timeout )); err != nil {
224+ if err : = c .SetDeadline (time .Now ().Add (conf .Timeout )); err != nil {
197225 return fmt .Errorf ("unable to set timeout: %v" , err )
198226 }
199227 }
@@ -206,31 +234,9 @@ func OpenLive(conf *Config) error {
206234
207235 // file to write packets
208236 f := NewWriter (conf .File )
209- if err = f .WriteHeader (conf , in , snaplen ); err != nil {
237+ if err : = f .WriteHeader (conf , in , snaplen ); err != nil {
210238 return err
211239 }
212- // number of packets
213- count := conf .PacketCount
214- if count < 0 {
215- count = 0
216- }
217- infinity := count == 0
218-
219- defer func () {
220- stats , err := c .Stats ()
221- if err != nil {
222- fmt .Printf ("failed to fetch stats: %v" , err )
223- }
224- // Received some data, assume some Stats were populated.
225- if stats .Packets == 0 {
226- fmt .Println ("stats indicated 0 received packets" )
227- }
228-
229- fmt .Fprintf (f .w , "- Packets: %d, Drops: %d, Freeze Queue Count: %d\n - Packets Captured: %d\n " ,
230- stats .Packets , stats .Drops , stats .FreezeQueueCount , f .packetNum )
231- // close Conn
232- c .Close ()
233- }()
234240
235241 // pcap file to write packets
236242 var pcap * mpcap.Writer
@@ -242,7 +248,7 @@ func OpenLive(conf *Config) error {
242248 }
243249 defer fpcap .Close ()
244250 pcap = mpcap .NewWriter (fpcap )
245- if err = pcap .WriteHeader (snaplen ); err != nil {
251+ if err : = pcap .WriteHeader (snaplen ); err != nil {
246252 return err
247253 }
248254 }
@@ -257,11 +263,30 @@ func OpenLive(conf *Config) error {
257263 }
258264 defer fpcapng .Close ()
259265 pcapng = mpcapng .NewWriter (fpcapng )
260- if err = pcapng .WriteHeader ("mshark" , in , conf .Expr , conf . Snaplen ); err != nil {
266+ if err : = pcapng .WriteHeader ("mshark" , in , conf .Expr , snaplen ); err != nil {
261267 return err
262268 }
263269 }
264270
271+ defer func () {
272+ stats , err := c .Stats ()
273+ if err != nil {
274+ fmt .Fprintf (os .Stderr , "failed to fetch stats: %v" , err )
275+ } else {
276+ fmt .Fprintf (f .w , "- Packets: %d, Drops: %d, Freeze Queue Count: %d\n - Packets Captured: %d\n " ,
277+ stats .Packets , stats .Drops , stats .FreezeQueueCount , f .packetNum )
278+ }
279+ // close Conn
280+ c .Close ()
281+ }()
282+
283+ // number of packets
284+ count := conf .PacketCount
285+ if count < 0 {
286+ count = 0
287+ }
288+ infinity := count == 0
289+
265290 for i := 0 ; infinity || i < count ; i ++ {
266291 n , _ , err := c .ReadFrom (b )
267292 if err != nil {
@@ -275,19 +300,19 @@ func OpenLive(conf *Config) error {
275300 data := b [:n ]
276301
277302 if conf .Pcap {
278- if err = pcap .WritePacket (timestamp , data ); err != nil {
303+ if err : = pcap .WritePacket (timestamp , data ); err != nil {
279304 return err
280305 }
281306 }
282307
283308 if conf .PcapNG {
284- if err = pcapng .WritePacket (timestamp , data ); err != nil {
309+ if err : = pcapng .WritePacket (timestamp , data ); err != nil {
285310 return err
286311 }
287312 }
288313
289- if err = f .WritePacket (timestamp , data ); err != nil {
290- fmt . Fprintln ( os . Stderr , err )
314+ if err : = f .WritePacket (timestamp , data ); err != nil {
315+ return err
291316 }
292317 }
293318 return nil
0 commit comments