Skip to content

Commit e4f8b89

Browse files
author
shadowy-pycoder
committed
Added verbose mode, small refactoring
1 parent d708204 commit e4f8b89

File tree

18 files changed

+252
-91
lines changed

18 files changed

+252
-91
lines changed

cmd/mshark/cli.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func root(args []string) error {
9898
})
9999
flags.DurationVar(&conf.Timeout, "t", 0, "The maximum duration of the packet capture process. Example: 5s")
100100
flags.IntVar(&conf.PacketCount, "c", 0, "The maximum number of packets to capture.")
101-
flags.StringVar(&conf.Expr, "e", "", `BPF filter expression. Example: "ip proto tcp"`)
101+
flags.StringVar(&conf.Expr, "e", "", `BPF filter expression. Example: "ip proto tcp".`)
102102
flags.BoolFunc("D", "Display list of interfaces and exit.", func(flagValue string) error {
103103
if err := displayInterfaces(); err != nil {
104104
fmt.Fprintf(os.Stderr, "%s: %v\n", app, err)
@@ -107,6 +107,11 @@ func root(args []string) error {
107107
os.Exit(0)
108108
return nil
109109
})
110+
var verbose bool
111+
flags.BoolFunc("v", "Display full packet info when capturing to stdout or txt.", func(flagValue string) error {
112+
verbose = true
113+
return nil
114+
})
110115
exts := ExtFlag([]string{})
111116
flags.TextVar(&exts, "f", &exts, "File extension(s) to write captured data. Supported formats: stdout, txt, pcap, pcapng")
112117

@@ -138,7 +143,7 @@ func root(args []string) error {
138143
for _, ext := range exts {
139144
switch ext {
140145
case "stdout":
141-
w := ms.NewWriter(os.Stdout)
146+
w := ms.NewWriter(os.Stdout, verbose)
142147
if err := w.WriteHeader(&conf); err != nil {
143148
return err
144149
}
@@ -149,7 +154,7 @@ func root(args []string) error {
149154
return err
150155
}
151156
defer f.Close()
152-
w := ms.NewWriter(f)
157+
w := ms.NewWriter(f, verbose)
153158
if err := w.WriteHeader(&conf); err != nil {
154159
return err
155160
}
@@ -182,7 +187,7 @@ func root(args []string) error {
182187
}
183188
}
184189
} else {
185-
w := ms.NewWriter(os.Stdout)
190+
w := ms.NewWriter(os.Stdout, verbose)
186191
if err := w.WriteHeader(&conf); err != nil {
187192
return err
188193
}

layers/arp.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ const headerSizeARP = 28
1414
// associated with a given internet layer address, typically an IPv4 address.
1515
// Defined in RFC 826.
1616
type ARPPacket struct {
17-
HardwareType uint16 // Network link protocol type.
18-
ProtocolType uint16 // Internetwork protocol for which the ARP request is intended.
19-
Hlen uint8 // Length (in octets) of a hardware address.
20-
Plen uint8 // Length (in octets) of internetwork addresses.
21-
Op uint16 // Specifies the operation that the sender is performing.
17+
HardwareType uint16 // Network link protocol type.
18+
ProtocolType uint16 // Internetwork protocol for which the ARP request is intended.
19+
ProtocolTypeDesc string // Internetwork protocol description.
20+
Hlen uint8 // Length (in octets) of a hardware address.
21+
Plen uint8 // Length (in octets) of internetwork addresses.
22+
Op uint16 // Specifies the operation that the sender is performing.
23+
OpDesc string // Operation description.
2224
// Media address of the sender. In an ARP request this field is used to indicate
2325
// the address of the host sending the request. In an ARP reply this field is used
2426
// to indicate the address of the host that the request was looking for.
@@ -31,7 +33,7 @@ type ARPPacket struct {
3133
}
3234

3335
func (ap *ARPPacket) String() string {
34-
return fmt.Sprintf(`ARP Packet:
36+
return fmt.Sprintf(`%s
3537
- Hardware Type: %d
3638
- Protocol Type: %s (%#04x)
3739
- HLen: %d
@@ -42,12 +44,13 @@ func (ap *ARPPacket) String() string {
4244
- Target MAC Address: %s
4345
- Target IP Address: %s
4446
`,
47+
ap.Summary(),
4548
ap.HardwareType,
46-
ap.ptype(),
49+
ap.ProtocolTypeDesc,
4750
ap.ProtocolType,
4851
ap.Hlen,
4952
ap.Plen,
50-
ap.op(),
53+
ap.OpDesc,
5154
ap.Op,
5255
ap.SenderMAC,
5356
ap.SenderIP,
@@ -56,16 +59,31 @@ func (ap *ARPPacket) String() string {
5659
)
5760
}
5861

62+
func (ap *ARPPacket) Summary() string {
63+
var message string
64+
switch ap.OpDesc {
65+
case "request":
66+
message = fmt.Sprintf("ARP Packet: (%s) Who has %s? Tell %s", ap.OpDesc, ap.TargetIP, ap.SenderIP)
67+
case "reply":
68+
message = fmt.Sprintf("ARP Packet: (%s) %s at %s", ap.OpDesc, ap.SenderIP, ap.SenderMAC)
69+
default:
70+
message = fmt.Sprintf("ARP Packet: (%s)", ap.OpDesc)
71+
}
72+
return message
73+
}
74+
5975
// Parse parses the given ARP packet data into the ARPPacket struct.
6076
func (ap *ARPPacket) Parse(data []byte) error {
6177
if len(data) < headerSizeARP {
6278
return fmt.Errorf("minimum header size for ARP is %d bytes, got %d bytes", headerSizeARP, len(data))
6379
}
6480
ap.HardwareType = binary.BigEndian.Uint16(data[0:2])
6581
ap.ProtocolType = binary.BigEndian.Uint16(data[2:4])
82+
ap.ProtocolTypeDesc = ap.ptype()
6683
ap.Hlen = data[4]
6784
ap.Plen = data[5]
6885
ap.Op = binary.BigEndian.Uint16(data[6:8])
86+
ap.OpDesc = ap.op()
6987
hoffset := 8 + ap.Hlen
7088
ap.SenderMAC = net.HardwareAddr(data[8:hoffset])
7189
poffset := hoffset + ap.Plen

layers/dns.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ type DNSMessage struct {
2020
}
2121

2222
func (d *DNSMessage) String() string {
23-
return fmt.Sprintf(`DNS Message:
24-
- Transaction ID: %#04x
23+
return fmt.Sprintf(`%s- Transaction ID: %#04x
2524
- Flags: %#04x
2625
%s
2726
- Questions: %d
2827
- Answer RRs: %d
2928
- Authority RRs: %d
3029
- Additional RRs: %d
31-
%s
32-
`,
30+
%s`,
31+
d.Summary(),
3332
d.TransactionID,
3433
d.Flags,
3534
d.flags(),
@@ -41,6 +40,10 @@ func (d *DNSMessage) String() string {
4140
)
4241
}
4342

43+
func (d *DNSMessage) Summary() string {
44+
return fmt.Sprint("DNS Message:")
45+
}
46+
4447
// Parse parses the given byte data into a DNSMessage struct.
4548
func (d *DNSMessage) Parse(data []byte) error {
4649
if len(data) < headerSizeDNS {

layers/ethernet.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,33 @@ const headerSizeEthernet = 14
1111

1212
// An Ethernet frame is a data link layer protocol data unit.
1313
type EthernetFrame struct {
14-
DstMAC net.HardwareAddr // MAC address of the destination device.
15-
SrcMAC net.HardwareAddr // MAC address of the source device.
16-
EtherType uint16 // The protocol of the upper layer.
17-
payload []byte
14+
DstMAC net.HardwareAddr // MAC address of the destination device.
15+
SrcMAC net.HardwareAddr // MAC address of the source device.
16+
EtherType uint16 // The protocol of the upper layer.
17+
EtherTypeDesc string // Protocol description
18+
payload []byte
1819
}
1920

2021
func (ef *EthernetFrame) String() string {
21-
ethType, _ := ef.NextLayer()
22-
return fmt.Sprintf(`Ethernet Frame:
22+
return fmt.Sprintf(`%s
2323
- DstMAC: %s
2424
- SrcMAC: %s
2525
- EtherType: %s (%#04x)
2626
- Payload: %d bytes
2727
%s`,
28+
ef.Summary(),
2829
ef.DstMAC,
2930
ef.SrcMAC,
30-
ethType,
31+
ef.EtherTypeDesc,
3132
ef.EtherType,
3233
len(ef.payload),
3334
hex.Dump(ef.payload))
3435
}
3536

37+
func (ef *EthernetFrame) Summary() string {
38+
return fmt.Sprintf("Ethernet Frame: Src: %s Dst: %s", ef.SrcMAC, ef.DstMAC)
39+
}
40+
3641
// Parse parses the given byte data into an Ethernet frame.
3742
func (ef *EthernetFrame) Parse(data []byte) error {
3843
if len(data) < headerSizeEthernet {
@@ -42,6 +47,7 @@ func (ef *EthernetFrame) Parse(data []byte) error {
4247
ef.SrcMAC = net.HardwareAddr(data[6:12])
4348
ef.EtherType = binary.BigEndian.Uint16(data[12:14])
4449
ef.payload = data[headerSizeEthernet:]
50+
ef.EtherTypeDesc, _ = ef.NextLayer()
4551
return nil
4652
}
4753

layers/ftp.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ type FTPMessage struct {
77
}
88

99
func (f *FTPMessage) String() string {
10-
return fmt.Sprintf(`FTP Message:
11-
%s
12-
`, f.payload)
10+
return fmt.Sprintf(`%s
11+
%s`, f.Summary(), f.payload)
12+
}
13+
14+
func (f *FTPMessage) Summary() string {
15+
return fmt.Sprint("FTP Message:")
1316
}
1417

1518
func (f *FTPMessage) Parse(data []byte) error {

layers/http.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ type HTTPMessage struct {
99
}
1010

1111
func (h *HTTPMessage) String() string {
12-
return fmt.Sprintf(`HTTP Message:
13-
%s
14-
`, h.payload)
12+
return fmt.Sprintf(`%s
13+
%s`, h.Summary(), h.payload)
14+
}
15+
func (h *HTTPMessage) Summary() string {
16+
return fmt.Sprint("HTTP Message:")
1517
}
1618

1719
func (h *HTTPMessage) Parse(data []byte) error {

layers/icmp.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,37 @@ const headerSizeICMP = 4
1010

1111
// ICMP is part of the Internet protocol suite as defined in RFC 792.
1212
type ICMPSegment struct {
13-
Type uint8 // ICMP type.
14-
Code uint8 // ICMP subtype.
13+
Type uint8 // ICMP type.
14+
TypeDesc string // ICMP type description.
15+
Code uint8 // ICMP subtype.
16+
CodeDesc string // ICMP subtype description.
1517
// Internet checksum (RFC 1071) for error checking, calculated from the ICMP header
1618
// and data with value 0 substituted for this field.
1719
Checksum uint16
1820
Data []byte // Contents vary based on the ICMP type and code.
1921
}
2022

2123
func (i *ICMPSegment) String() string {
22-
mtype, code := i.typecode()
23-
return fmt.Sprintf(`ICMP Segment:
24+
return fmt.Sprintf(`%s
2425
- Type: %d (%s)
2526
- Code: %d (%s)
2627
- Checksum: %#04x
2728
%s
2829
`,
30+
i.Summary(),
2931
i.Type,
30-
mtype,
32+
i.TypeDesc,
3133
i.Code,
32-
code,
34+
i.CodeDesc,
3335
i.Checksum,
3436
i.data(),
3537
)
3638
}
3739

40+
func (i *ICMPSegment) Summary() string {
41+
return fmt.Sprintf("ICMP Segment: %s (%s)", i.TypeDesc, i.CodeDesc)
42+
}
43+
3844
// Parse parses the given byte data into an ICMP segment struct.
3945
func (i *ICMPSegment) Parse(data []byte) error {
4046
if len(data) < headerSizeICMP {
@@ -56,6 +62,7 @@ func (i *ICMPSegment) Parse(data []byte) error {
5662
if len(i.Data) < pLen {
5763
return fmt.Errorf("minimum payload length for ICMP with type %d is %d bytes", i.Type, pLen)
5864
}
65+
i.TypeDesc, i.CodeDesc = i.typecode()
5966
return nil
6067
}
6168
func (i *ICMPSegment) NextLayer() (string, []byte) {

layers/icmpv6.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,34 @@ const headerSizeICMPv6 = 4
1111
// ICMPv6 is an integral part of IPv6 and performs error reporting and diagnostic functions.
1212
type ICMPv6Segment struct {
1313
Type uint8
14+
TypeDesc string
1415
Code uint8
16+
CodeDesc string
1517
Checksum uint16
1618
Data []byte
1719
}
1820

1921
func (i *ICMPv6Segment) String() string {
20-
mtype, code := i.typecode()
21-
return fmt.Sprintf(`ICMPv6 Segment:
22+
return fmt.Sprintf(`%s
2223
- Type: %d (%s)
2324
- Code: %d (%s)
2425
- Checksum: %#04x
2526
%s
2627
`,
28+
i.Summary(),
2729
i.Type,
28-
mtype,
30+
i.TypeDesc,
2931
i.Code,
30-
code,
32+
i.CodeDesc,
3133
i.Checksum,
3234
i.data(),
3335
)
3436
}
3537

38+
func (i *ICMPv6Segment) Summary() string {
39+
return fmt.Sprintf("ICMPv6 Segment: %s (%s)", i.TypeDesc, i.CodeDesc)
40+
}
41+
3642
// Parse parses the given byte data into an ICMPv6 segment struct.
3743
func (i *ICMPv6Segment) Parse(data []byte) error {
3844
if len(data) < headerSizeICMPv6 {
@@ -58,6 +64,7 @@ func (i *ICMPv6Segment) Parse(data []byte) error {
5864
if len(i.Data) < pLen {
5965
return fmt.Errorf("minimum payload length for ICMPv6 with type %d is %d bytes", i.Type, pLen)
6066
}
67+
i.TypeDesc, i.CodeDesc = i.typecode()
6168
return nil
6269
}
6370

0 commit comments

Comments
 (0)