diff --git a/README.md b/README.md index 79d0b5f..e41a5d7 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,14 @@ Received 0 response(s) $ nslookup -vc github.com ``` +#### ipv6でping +どうするか + +```console +$ ip -6 route +$ ping -c 1 fe80::1 +``` + ### 動作確認の様子
xxx diff --git a/cmd/packemon/main.go b/cmd/packemon/main.go index 5af8fc2..1b32e67 100644 --- a/cmd/packemon/main.go +++ b/cmd/packemon/main.go @@ -52,19 +52,25 @@ func run(nwInterface string, wantSend bool, debug bool, protocol string) error { tui.DEFAULT_ARP_SENDER_IP = tui.DEFAULT_IP_SOURCE if debug { - if wantSend && protocol == "tcp-3way-http" { - dstIPAddr := make([]byte, 4) - binary.BigEndian.PutUint32(dstIPAddr, 0xc0a80a6e) // 192.168.10.110 - var dstPort uint16 = 0x0050 // 80 - httpGet := packemon.NewHTTP() - return packemon.EstablishConnectionAndSendPayload(nwInterface, dstIPAddr, dstPort, httpGet.Bytes()) + if wantSend { + if protocol == "tcp-3way-http" { + dstIPAddr := make([]byte, 4) + binary.BigEndian.PutUint32(dstIPAddr, 0xc0a80a6e) // 192.168.10.110 + var dstPort uint16 = 0x0050 // 80 + httpGet := packemon.NewHTTP() + return packemon.EstablishConnectionAndSendPayload(nwInterface, dstIPAddr, dstPort, httpGet.Bytes()) + } + + // PC再起動とかでdstのMACアドレス変わるみたい。以下で調べてdst正しいのにする + // $ ip route + // $ arp xxx.xx.xxx.1 + firsthopMACAddr := [6]byte{0x00, 0x15, 0x5d, 0x8c, 0xc2, 0x6b} + return debugMode(wantSend, protocol, netIf, firsthopMACAddr) } - // PC再起動とかでdstのMACアドレス変わるみたい。以下で調べてdst正しいのにする - // $ ip route - // $ arp xxx.xx.xxx.1 - firsthopMACAddr := [6]byte{0x00, 0x15, 0x5d, 0x8c, 0xc2, 0x6b} - return debugMode(wantSend, protocol, netIf, firsthopMACAddr) + // Monitor の debug は本チャンの networkinterface.go 使うようにする + go netIf.Recieve() + return debugPrint(netIf.PassiveCh) } if wantSend { @@ -78,6 +84,18 @@ func run(nwInterface string, wantSend bool, debug bool, protocol string) error { } } +func debugPrint(passive <-chan *packemon.Passive) error { + for p := range passive { + if p.HighLayerProto() == "IPv6" { + fmt.Println("Passive!") + fmt.Printf("%x\n", p.IPv6) + } + + } + + return nil +} + func debugMode(wantSend bool, protocol string, netIf *packemon.NetworkInterface, dstMacAddr [6]byte) error { debugNetIf := debugging.NewDebugNetworkInterface(netIf) defer debugNetIf.Close() diff --git a/internal/tui/history.go b/internal/tui/history.go index af72f04..9d1922b 100644 --- a/internal/tui/history.go +++ b/internal/tui/history.go @@ -71,6 +71,10 @@ func (t *tui) updateTable(passiveCh <-chan *packemon.Passive) { viewIPv4 := &IPv4{passive.IPv4} r.destinationIPAddr = tview.NewTableCell(fmt.Sprintf("DstIP:%s", viewIPv4.StrDstIPAddr())).SetTextColor(tcell.Color51) r.sourceIPAddr = tview.NewTableCell(fmt.Sprintf("SrcIP:%s", viewIPv4.StrSrcIPAddr())).SetTextColor(tcell.Color181) + } else if passive.IPv6 != nil { + viewIPv6 := &IPv6{passive.IPv6} + r.destinationIPAddr = tview.NewTableCell(fmt.Sprintf("DstIP:%s", viewIPv6.StrDstIPAddr())).SetTextColor(tcell.Color51) + r.sourceIPAddr = tview.NewTableCell(fmt.Sprintf("SrcIP:%s", viewIPv6.StrSrcIPAddr())).SetTextColor(tcell.Color181) } else { r.destinationIPAddr = tview.NewTableCell(fmt.Sprintf("DstIP:%s", "-")).SetTextColor(tcell.Color51) r.sourceIPAddr = tview.NewTableCell(fmt.Sprintf("SrcIP:%s", "-")).SetTextColor(tcell.Color181) diff --git a/internal/tui/view.go b/internal/tui/view.go index f117c6d..464abf4 100644 --- a/internal/tui/view.go +++ b/internal/tui/view.go @@ -56,6 +56,9 @@ func passiveToViewers(passive *packemon.Passive) []Viewer { if passive.IPv4 != nil { viewers = append(viewers, &IPv4{passive.IPv4}) } + if passive.IPv6 != nil { + viewers = append(viewers, &IPv6{passive.IPv6}) + } if passive.ICMP != nil { viewers = append(viewers, &ICMP{passive.ICMP}) } diff --git a/internal/tui/view_ipv6.go b/internal/tui/view_ipv6.go new file mode 100644 index 0000000..0711c19 --- /dev/null +++ b/internal/tui/view_ipv6.go @@ -0,0 +1,65 @@ +package tui + +import ( + "fmt" + "net" + + "github.com/ddddddO/packemon" + "github.com/rivo/tview" +) + +type IPv6 struct { + *packemon.IPv6 +} + +func (*IPv6) rows() int { + return 16 +} + +func (*IPv6) columns() int { + return 30 +} + +func (i *IPv6) viewTable() *tview.Table { + table := tview.NewTable().SetBorders(false) + table.Box = tview.NewBox().SetBorder(true).SetTitle(" IPv6 Header ").SetTitleAlign(tview.AlignLeft).SetBorderPadding(1, 1, 1, 1) + + table.SetCell(0, 0, tview.NewTableCell(padding("Version"))) + table.SetCell(0, 1, tview.NewTableCell(padding(fmt.Sprintf("%x", i.Version)))) + + table.SetCell(1, 0, tview.NewTableCell(padding("Traffic Class"))) + table.SetCell(1, 1, tview.NewTableCell(padding(fmt.Sprintf("%x", i.TrafficClass)))) + + table.SetCell(2, 0, tview.NewTableCell(padding("Flow Label"))) + table.SetCell(2, 1, tview.NewTableCell(padding(""))) + + table.SetCell(3, 0, tview.NewTableCell(padding("Payload Length"))) + table.SetCell(3, 1, tview.NewTableCell(padding(""))) + + table.SetCell(4, 0, tview.NewTableCell(padding("Next Header"))) + table.SetCell(4, 1, tview.NewTableCell(padding(fmt.Sprintf("%x", i.NextHeader)))) + + table.SetCell(5, 0, tview.NewTableCell(padding("Hop Limit"))) + table.SetCell(5, 1, tview.NewTableCell(padding(fmt.Sprintf("%d", i.HopLimit)))) + + table.SetCell(6, 0, tview.NewTableCell(padding("Source Address"))) + table.SetCell(6, 1, tview.NewTableCell(padding(i.StrSrcIPAddr()))) + + table.SetCell(7, 0, tview.NewTableCell(padding("Destination Address"))) + table.SetCell(7, 1, tview.NewTableCell(padding(i.StrDstIPAddr()))) + + return table +} + +func (i *IPv6) StrSrcIPAddr() string { + return uintsToStrIPv6Addr(i.SrcAddr) +} + +func (i *IPv6) StrDstIPAddr() string { + return uintsToStrIPv6Addr(i.DstAddr) +} + +func uintsToStrIPv6Addr(byteAddr []uint8) string { + ipv6Addr := net.IP(byteAddr) + return ipv6Addr.To16().String() +} diff --git a/ipv6.go b/ipv6.go new file mode 100644 index 0000000..bd5c45b --- /dev/null +++ b/ipv6.go @@ -0,0 +1,35 @@ +package packemon + +// https://atmarkit.itmedia.co.jp/ait/articles/1201/05/news113.html +type IPv6 struct { + Version uint8 // 4bit + TrafficClass uint8 + FlowLabel uint32 // 20bit + PayloadLength uint16 + NextHeader uint8 + HopLimit uint8 + SrcAddr []uint8 + DstAddr []uint8 + + Option []uint8 + + Data []byte +} + +func ParsedIPv6(payload []byte) *IPv6 { + return &IPv6{ + Version: payload[0] >> 4, + TrafficClass: payload[0]<<4 | payload[1]>>4, + // FlowLabel: , + // PayloadLength: , + NextHeader: payload[6], + HopLimit: payload[7], + SrcAddr: payload[8:24], + DstAddr: payload[24:40], + } +} + +const ( + IPv6_NEXT_HEADER_UDP = 0x11 + IPv6_NEXT_HEADER_ICMPv6 = 0x3a +) diff --git a/networkinterface.go b/networkinterface.go index c65376f..1cdf953 100644 --- a/networkinterface.go +++ b/networkinterface.go @@ -230,6 +230,12 @@ func ParsedPacket(recieved []byte) *Passive { IPv4: ipv4, } } + case ETHER_TYPE_IPv6: + ipv6 := ParsedIPv6(ethernetFrame.Data) + return &Passive{ + EthernetFrame: ethernetFrame, + IPv6: ipv6, + } default: return &Passive{ diff --git a/passive.go b/passive.go index a9d33f6..b90a989 100644 --- a/passive.go +++ b/passive.go @@ -8,6 +8,7 @@ type Passive struct { UDP *UDP ICMP *ICMP IPv4 *IPv4 + IPv6 *IPv6 ARP *ARP EthernetFrame *EthernetFrame } @@ -23,6 +24,9 @@ func (p *Passive) HighLayerProto() string { if p.IPv4 != nil { proto = "IPv4" } + if p.IPv6 != nil { + proto = "IPv6" + } if p.ICMP != nil { proto = "ICMP" }