Skip to content

Commit

Permalink
Merge pull request #74 from ddddddO/16dump
Browse files Browse the repository at this point in the history
impl view hexadecimal dump
  • Loading branch information
ddddddO authored Jan 2, 2025
2 parents ad94780 + febf46d commit 829b977
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
26 changes: 26 additions & 0 deletions internal/tui/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,41 +47,67 @@ func (t *tui) updateView(passive *packemon.Passive) {

func passiveToViewers(passive *packemon.Passive) []Viewer {
viewers := []Viewer{}
hexdump := &HexadecimalDump{}
if passive.EthernetFrame != nil {
viewers = append(viewers, &EthernetFrame{passive.EthernetFrame})
hexdump.EthernetFrame = passive.EthernetFrame
}
if passive.ARP != nil {
viewers = append(viewers, &ARP{passive.ARP})
hexdump.ARP = passive.ARP
}
if passive.IPv4 != nil {
viewers = append(viewers, &IPv4{passive.IPv4})
hexdump.IPv4 = passive.IPv4
}
if passive.IPv6 != nil {
viewers = append(viewers, &IPv6{passive.IPv6})
hexdump.IPv6 = passive.IPv6
}
if passive.ICMP != nil {
viewers = append(viewers, &ICMP{passive.ICMP})
hexdump.ICMP = passive.ICMP
}
if passive.TCP != nil {
viewers = append(viewers, &TCP{passive.TCP})
hexdump.TCP = passive.TCP
}
if passive.UDP != nil {
viewers = append(viewers, &UDP{passive.UDP})
hexdump.UDP = passive.UDP
}
if passive.DNS != nil {
viewers = append(viewers, &DNS{passive.DNS})
hexdump.DNS = passive.DNS
}
if passive.HTTP != nil {
viewers = append(viewers, &HTTP{passive.HTTP})
hexdump.HTTP = passive.HTTP
}
if passive.HTTPRes != nil {
viewers = append(viewers, &HTTPResponse{passive.HTTPRes})
hexdump.HTTPResponse = passive.HTTPRes
}

viewers = append(viewers, hexdump)

return viewers
}

func padding(s string) string {
spaces := strings.Repeat(" ", 3)
return fmt.Sprintf("%s%s%s", spaces, s, spaces)
}

func spacer(bb []byte) string {
ret := ""
for i, b := range bb {
ret += fmt.Sprintf("%02x ", b)

// 8byte毎に、大きくスペースとる
if (i+1)%8 == 0 {
ret += " "
}
}
return ret
}
161 changes: 161 additions & 0 deletions internal/tui/view_hexadecimal_dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package tui

import (
"github.com/ddddddO/packemon"
"github.com/rivo/tview"
)

type HexadecimalDump struct {
*packemon.EthernetFrame
*packemon.ARP
*packemon.IPv4
*packemon.IPv6
*packemon.ICMP
*packemon.TCP
*packemon.UDP
*packemon.DNS
*packemon.HTTP
*packemon.HTTPResponse

data []byte
}

func (h *HexadecimalDump) rows() int {
return 20
}

func (*HexadecimalDump) columns() int {
return 30
}

// TODO: 似た構造あるからそこ共通化
func (h *HexadecimalDump) viewTable() *tview.Table {
table := tview.NewTable().SetBorders(false)
table.Box = tview.NewBox().SetBorder(true).SetTitle(" Hexadecimal dump ").SetTitleAlign(tview.AlignLeft).SetBorderPadding(1, 1, 1, 1)

// L2
switch {
case h.EthernetFrame != nil:
const ethernetHeaderLength = 14
table.SetCell(0, 0, tview.NewTableCell(padding("Ethernet")))
table.SetCell(0, 1, tview.NewTableCell(padding(spacer(h.EthernetFrame.Bytes()[0:ethernetHeaderLength]))))
}

// L3
loopForL3View := 1
switch {
case h.ARP != nil:
table.SetCell(loopForL3View, 0, tview.NewTableCell(padding("ARP")))

arpBytes := h.ARP.Bytes()
for i := 0; ; i += 16 {
if len(arpBytes) < i+16 {
table.SetCell(loopForL3View, 1, tview.NewTableCell(padding(spacer(arpBytes[i:]))))
break
}
table.SetCell(loopForL3View, 1, tview.NewTableCell(padding(spacer(arpBytes[i:i+16]))))

loopForL3View++
}

case h.IPv4 != nil:
table.SetCell(loopForL3View, 0, tview.NewTableCell(padding("IPv4")))

ipv4Bytes := h.IPv4.Bytes()[0 : h.IPv4.Ihl*4]
for i := 0; ; i += 16 {
if len(ipv4Bytes) < i+16 {
table.SetCell(loopForL3View, 1, tview.NewTableCell(padding(spacer(ipv4Bytes[i:]))))
break
}
table.SetCell(loopForL3View, 1, tview.NewTableCell(padding(spacer(ipv4Bytes[i:i+16]))))

loopForL3View++
}

case h.IPv6 != nil:
table.SetCell(loopForL3View, 0, tview.NewTableCell(padding("IPv6")))
// TODO: IPv6.Bytes()
// table.SetCell(loopForL3View, 1, tview.NewTableCell(padding(spacer("%x", h.IPv6)))
}

// L4
const udpHeaderLength = 8
loopForL4View := 1 + loopForL3View
switch {
case h.ICMP != nil:
table.SetCell(loopForL4View, 0, tview.NewTableCell(padding("ICMP")))

icmpBytes := h.ICMP.Bytes()
for i := 0; ; i += 16 {
if len(icmpBytes) < i+16 {
table.SetCell(loopForL4View, 1, tview.NewTableCell(padding(spacer(icmpBytes[i:]))))
break
}
table.SetCell(loopForL4View, 1, tview.NewTableCell(padding(spacer(icmpBytes[i:i+16]))))

loopForL4View++
}

case h.TCP != nil:
table.SetCell(loopForL4View, 0, tview.NewTableCell(padding("TCP")))

tcpBytes := h.TCP.Bytes()[0 : h.TCP.HeaderLength/4]
for i := 0; ; i += 16 {
if len(tcpBytes) < i+16 {
table.SetCell(loopForL4View, 1, tview.NewTableCell(padding(spacer(tcpBytes[i:]))))
break
} else {
table.SetCell(loopForL4View, 1, tview.NewTableCell(padding(spacer(tcpBytes[i:i+16]))))
}
loopForL4View++
}
case h.UDP != nil:
table.SetCell(loopForL4View, 0, tview.NewTableCell(padding("UDP")))
table.SetCell(loopForL4View, 1, tview.NewTableCell(padding(spacer(h.UDP.Bytes()[0:udpHeaderLength]))))
}

// L7
loopForL7View := 1 + loopForL4View
switch {
case h.DNS != nil:
table.SetCell(loopForL7View, 0, tview.NewTableCell(padding("DNS")))
if h.UDP != nil {
dnsBytes := h.DNS.Bytes()[0 : h.UDP.Length-udpHeaderLength]
for i := 0; ; i += 16 {
if len(dnsBytes) < i+16 {
table.SetCell(loopForL7View, 1, tview.NewTableCell(padding(spacer(dnsBytes[i:]))))
break
} else {
table.SetCell(loopForL7View, 1, tview.NewTableCell(padding(spacer(dnsBytes[i:i+16]))))
}

loopForL7View++
}

}
if h.TCP != nil {
// TODO:
}
case h.HTTP != nil:
table.SetCell(loopForL7View, 0, tview.NewTableCell(padding("HTTP")))

httpBytes := h.HTTP.Bytes()
for i := 0; ; i += 16 {
if len(httpBytes) < i+16 {
table.SetCell(loopForL7View, 1, tview.NewTableCell(padding(spacer(httpBytes[i:]))))
break
} else {
table.SetCell(loopForL7View, 1, tview.NewTableCell(padding(spacer(httpBytes[i:i+16]))))
}

loopForL7View++
}

case h.HTTPResponse != nil:
table.SetCell(loopForL7View, 0, tview.NewTableCell(padding("HTTP")))
// TODO: HTTPResponse.Bytes()
// table.SetCell(loopForL7View, 1, tview.NewTableCell(padding(spacer(h.HTTPResponse)))
}

return table
}

0 comments on commit 829b977

Please sign in to comment.