diff --git a/cmd/termshark/termshark.go b/cmd/termshark/termshark.go index 0d36b62..272be4a 100644 --- a/cmd/termshark/termshark.go +++ b/cmd/termshark/termshark.go @@ -345,55 +345,6 @@ func cmain() int { } } - fileSrcs := pcap.FileSystemSources(psrcs) - if len(fileSrcs) == 1 { - if len(psrcs) > 1 { - fmt.Fprintf(os.Stderr, "You can't specify both a pcap and a live capture.\n") - return 1 - } - } else if len(fileSrcs) > 1 { - fmt.Fprintf(os.Stderr, "You can't specify more than one pcap.\n") - return 1 - } - - // Invariant: len(psrcs) > 0 - // Invariant: len(fileSrcs) == 1 => len(psrcs) == 1 - - // go-flags returns [""] when no extra args are provided, so I can't just - // test the length of this slice - argsFilter := strings.Join(filterArgs, " ") - - // Work out capture filter afterwards because we need to determine first - // whether any potential first argument is intended as a pcap file instead of - // a capture filter. - captureFilter := opts.CaptureFilter - - // Meaning there are only live captures - if len(fileSrcs) == 0 && argsFilter != "" { - if opts.CaptureFilter != "" { - fmt.Fprintf(os.Stderr, "Two capture filters provided - '%s' and '%s' - please supply one only.\n", opts.CaptureFilter, argsFilter) - return 1 - } - captureFilter = argsFilter - } - - displayFilter := opts.DisplayFilter - - // Validate supplied filters e.g. no capture filter when reading from file - if len(fileSrcs) > 0 { - if captureFilter != "" { - fmt.Fprintf(os.Stderr, "Cannot use a capture filter when reading from a pcap file - '%s' and '%s'.\n", captureFilter, pcapf) - return 1 - } - if argsFilter != "" { - if opts.DisplayFilter != "" { - fmt.Fprintf(os.Stderr, "Two display filters provided - '%s' and '%s' - please supply one only.\n", opts.DisplayFilter, argsFilter) - return 1 - } - displayFilter = argsFilter - } - } - // - means read from stdin. But termshark uses stdin for interacting with the UI. So if the // iface is -, then dup stdin to a free descriptor, adjust iface to read from that descriptor, // then open /dev/tty on stdin. @@ -401,7 +352,7 @@ func cmain() int { // Here we check for // (a) sources named '-' - these need rewritten to /dev/fd/N and stdin needs to be moved - // (b) fifo sources + // (b) fifo sources - these are switched from -r to -i because that's what tshark needs renamedStdin := false for pi, psrc := range psrcs { switch { @@ -430,7 +381,7 @@ func cmain() int { default: stat, err := os.Stat(psrc.Name()) if err != nil { - if len(fileSrcs) > 0 { + if psrc.IsFile() || psrc.IsFifo() { // Means this was supplied with -r - since any file sources means there's (a) 1 and (b) // no other sources. So it must stat. Note if we started with -i fifo, this check // isn't done... but it still ought to exist. @@ -458,6 +409,56 @@ func cmain() int { } } + // Means files + fileSrcs := pcap.FileSystemSources(psrcs) + if len(fileSrcs) == 1 { + if len(psrcs) > 1 { + fmt.Fprintf(os.Stderr, "You can't specify both a pcap and a live capture.\n") + return 1 + } + } else if len(fileSrcs) > 1 { + fmt.Fprintf(os.Stderr, "You can't specify more than one pcap.\n") + return 1 + } + + // Invariant: len(psrcs) > 0 + // Invariant: len(fileSrcs) == 1 => len(psrcs) == 1 + + // go-flags returns [""] when no extra args are provided, so I can't just + // test the length of this slice + argsFilter := strings.Join(filterArgs, " ") + + // Work out capture filter afterwards because we need to determine first + // whether any potential first argument is intended as a pcap file instead of + // a capture filter. + captureFilter := opts.CaptureFilter + + // Meaning there are only live captures + if len(fileSrcs) == 0 && argsFilter != "" { + if opts.CaptureFilter != "" { + fmt.Fprintf(os.Stderr, "Two capture filters provided - '%s' and '%s' - please supply one only.\n", opts.CaptureFilter, argsFilter) + return 1 + } + captureFilter = argsFilter + } + + displayFilter := opts.DisplayFilter + + // Validate supplied filters e.g. no capture filter when reading from file + if len(fileSrcs) > 0 { + if captureFilter != "" { + fmt.Fprintf(os.Stderr, "Cannot use a capture filter when reading from a pcap file - '%s' and '%s'.\n", captureFilter, pcapf) + return 1 + } + if argsFilter != "" { + if opts.DisplayFilter != "" { + fmt.Fprintf(os.Stderr, "Two display filters provided - '%s' and '%s' - please supply one only.\n", opts.DisplayFilter, argsFilter) + return 1 + } + displayFilter = argsFilter + } + } + // Here we now have an accurate view of all psrcs - either file, fifo, pipe or interface // Helpful to use logging when enumerating interfaces below, so do it first @@ -642,7 +643,7 @@ func cmain() int { // fifo. In all cases, we save the packets to a file so that if a // filter is applied, we can restart - and so that we preserve the // capture at the end of running termshark. - if len(fileSrcs) == 0 && startedSuccessfully { + if len(pcap.FileSystemSources(psrcs)) == 0 && startedSuccessfully { fmt.Printf("Packets read from %s have been saved in %s\n", pcap.SourcesString(psrcs), ifacePcapFilename) } }() @@ -710,7 +711,7 @@ func cmain() int { var iwatcher *fsnotify.Watcher var ifaceTmpFile string - if len(fileSrcs) == 0 { + if len(pcap.FileSystemSources(psrcs)) == 0 { srcNames := make([]string, 0, len(psrcs)) for _, psrc := range psrcs { srcNames = append(srcNames, psrc.Name()) @@ -793,6 +794,8 @@ func cmain() int { }, } + // Refresh + fileSrcs = pcap.FileSystemSources(psrcs) if len(fileSrcs) > 0 { psrc := fileSrcs[0] absfile, err := filepath.Abs(psrc.Name()) diff --git a/pcap/source.go b/pcap/source.go index 67db4c9..d9be1d7 100644 --- a/pcap/source.go +++ b/pcap/source.go @@ -5,6 +5,7 @@ package pcap import ( + "fmt" "os" "strings" @@ -26,7 +27,7 @@ type IPacketSource interface { func FileSystemSources(srcs []IPacketSource) []IPacketSource { res := make([]IPacketSource, 0) for _, src := range srcs { - if src.IsFile() || src.IsFifo() { + if src.IsFile() { res = append(res, src) } } @@ -85,6 +86,10 @@ func (p FileSource) IsPipe() bool { return false } +func (p FileSource) String() string { + return fmt.Sprintf("File:%s", p.Filename) +} + //====================================================================== type TemporaryFileSource struct { @@ -99,6 +104,10 @@ func (p TemporaryFileSource) Remove() error { return os.Remove(p.Filename) } +func (p TemporaryFileSource) String() string { + return fmt.Sprintf("TempFile:%s", p.Filename) +} + //====================================================================== type InterfaceSource struct { @@ -127,6 +136,10 @@ func (p InterfaceSource) IsPipe() bool { return false } +func (p InterfaceSource) String() string { + return fmt.Sprintf("Interface:%s", p.Iface) +} + //====================================================================== type FifoSource struct { @@ -155,6 +168,10 @@ func (p FifoSource) IsPipe() bool { return false } +func (p FifoSource) String() string { + return fmt.Sprintf("Fifo:%s", p.Filename) +} + //====================================================================== type PipeSource struct { @@ -189,6 +206,10 @@ func (p PipeSource) Close() error { return nil } +func (p PipeSource) String() string { + return fmt.Sprintf("Pipe:%s(%d)", p.Descriptor, p.Fd) +} + //====================================================================== // Local Variables: // mode: Go