[가기] TCP 패킷 캡처 시도
소개
TCP 패킷 캡처를 시도합니다.
TCP 소켓 통신
패킷을 캡처하기 위해 TCP 소켓 통신을 위한 애플리케이션을 만들 것입니다.
TCP 서버 샘플
package main
import (
"fmt"
"io"
"log"
"net"
)
func main() {
ln, err := net.Listen("tcp", ":8099")
if err != nil {
fmt.Println("cannot listen", err)
}
for {
conn, e := ln.Accept()
if e != nil {
log.Fatal(e)
return
}
go echo_handler(conn)
}
}
func echo_handler(conn net.Conn) {
defer conn.Close()
io.Copy(conn, conn)
}
tcp-클라이언트-샘플
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
ticker := time.NewTicker(time.Millisecond * 1000)
var conn net.Conn
var err error
defer func() {
ticker.Stop()
if conn != nil {
conn.Close()
}
}()
count := 0
for range ticker.C {
if count > 1000 {
break
}
conn, err = net.Dial("tcp", ":8099")
if err != nil {
log.Fatal(err)
}
sendData := []byte(fmt.Sprintf("Hello_%d", count))
_, err = conn.Write(sendData)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Println(string(buf[:n]))
conn.Close()
conn = nil
count += 1
}
}
TCP 패킷 캡처
gopacket/pcap으로 TCP 패킷을 캡처합니다.
libpcap-dev
Windows와 Xubuntu에 Wireshark를 이미 설치했기 때문에 다른 Windows용 소프트웨어를 설치할 필요가 없었습니다.
하지만 Xubuntu에서 gopacket/pcap을 실행하려고 하면 오류가 발생합니다.
# github.com/google/gopacket/pcap
../../../pkg/mod/github.com/google/[email protected]/pcap/pcap_unix.go:34:10: fatal error: pcap.h: No such file or directory
34 | #include <pcap.h>
| ^~~~~~~~
compilation terminated.
"libpcap-dev"를 설치해야 합니다.
sudo apt install -y libpcap-dev
샘플 캡처
tcp-캡처-샘플
package main
import (
"fmt"
"log"
"strings"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() {
loopbackDevice := getLoopbackDeviceName()
if loopbackDevice == "" {
log.Println("No loopback devices")
return
}
handle, err := pcap.OpenLive(loopbackDevice, 1024, false, 3*time.Second)
if err != nil {
log.Fatal(err)
}
defer handle.Close()
// Filtering capture targets
err = handle.SetBPFFilter("tcp and port 8099")
if err != nil {
log.Fatal(err)
}
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
// Get decoded packets through chann
for packet := range packetSource.Packets() {
log.Println("S-------S")
log.Println(packet)
log.Println("E-------E")
}
}
func getLoopbackDeviceName() string {
// Find all devices
devices, err := pcap.FindAllDevs()
if err != nil {
log.Fatal(err.Error())
}
for _, device := range devices {
// for Windows
if strings.Contains(strings.ToLower(device.Name), "loopback") ||
// for Xubuntu
device.Name == "lo" {
return device.Name
}
}
return ""
}
결과
...
2022/10/12 21:19:27 S-------S
2022/10/12 21:19:27 PACKET: 74 bytes, wire length 74 cap length 74 @ 2022-10-12 21:19:27.764308 +0900 JST
- Layer 1 (14 bytes) = Ethernet {Contents=[..14..] Payload=[..60..] SrcMAC=00:00:00:00:00:00 DstMAC=00:00:00:00:00:00 EthernetType=IPv4 Length=0}
- Layer 2 (20 bytes) = IPv4 {Contents=[..20..] Payload=[..40..] Version=4 IHL=5 TOS=0 Length=60 Id=36925 Flags=DF FragOffset=0 TTL=64 Protocol=TCP Checksum=44156 SrcIP=127.0.0.1 DstIP=127.0.0.1 Options=[] Padding=[]}
- Layer 3 (32 bytes) = TCP {Contents=[..32..] Payload=[..8..] SrcPort=8099 DstPort=57632 Seq=2020353806 Ack=775619635 DataOffset=8 FIN=false SYN=false RST=false PSH=true ACK=true URG=false ECE=false CWR=false NS=false Window=512 Checksum=65072 Urgent=0 Options=[TCPOption(NOP:), TCPOption(NOP:), TCPOption(Timestamps:3776381494/3776381494 0xe1170236e1170236)] Padding=[]}
- Layer 4 (08 bytes) = Payload 8 byte(s)
2022/10/12 21:19:27 E-------E
...
그 결과, 캡처된 패킷은 여러 계층의 데이터로 디코딩되었습니다.
...
func main() {
...
// Get decoded packets through chann
for packet := range packetSource.Packets() {
printPacketInfo(packet)
}
}
...
func printPacketInfo(packet gopacket.Packet) {
// TCP
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
fmt.Println("Sequence number: ", tcp.Seq)
}
// TCP/IPV4 Payload
applicationLayer := packet.ApplicationLayer()
if applicationLayer != nil {
fmt.Println("Application layer/Payload found.")
fmt.Printf("%s\n", applicationLayer.Payload())
}
// Check for errors
if err := packet.ErrorLayer(); err != nil {
fmt.Println("Error decoding some part of the packet:", err)
}
}
RFC 9293 - Transmission Control Protocol (TCP)
* RFC791 - INTERNET PROTOCOL
Reference
이 문제에 관하여([가기] TCP 패킷 캡처 시도), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/masanori_msl/go-try-capturing-tcp-packets-59cp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)