diff --git a/mazepa-server/go.mod b/mazepa-server/go.mod
@@ -2,9 +2,13 @@ module mazepa-server
go 1.24.1
-require github.com/spf13/cobra v1.9.1
+require (
+ github.com/spf13/cobra v1.9.1
+ golang.org/x/net v0.46.0
+)
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.6 // indirect
+ golang.org/x/sys v0.37.0 // indirect
)
diff --git a/mazepa-server/go.sum b/mazepa-server/go.sum
@@ -6,5 +6,9 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
+golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
+golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/mazepa-server/icmp/pkg.go b/mazepa-server/icmp/pkg.go
@@ -1,22 +1,83 @@
package icmp
import (
- "fmt"
+ "log"
"net"
+ "time"
+
+ "golang.org/x/net/icmp"
+ "golang.org/x/net/ipv4"
)
-/*
- https://darkcoding.net/uncategorized/raw-sockets-in-go-ip-layer
-*/
+// The network must be "ip4:icmp" for IPv4 ICMP.
+const network = "ip4:icmp"
func ListenAndPrint(addr string) {
- netaddr, _ := net.ResolveIPAddr("ip4", addr)
- conn, _ := net.ListenIP("ip4:icmp", netaddr)
+ conn, err := icmp.ListenPacket(network, "0.0.0.0")
+ if err != nil {
+ log.Fatalf("ListenPacket failed: %v\nRun with sudo or elevated permissions.", err)
+ }
+ defer conn.Close()
+
+ log.Printf("Listening for ICMP packets on %s...", conn.LocalAddr().String())
+ rb := make([]byte, 1500)
+
+ for {
+ /* Set a read deadline to prevent the program from blocking indefinitely */
+ err := conn.SetReadDeadline(time.Now().Add(time.Second * 5))
+ if err != nil {
+ log.Printf("Error setting read deadline: %v", err)
+ continue
+ }
+
+ n, peer, err := conn.ReadFrom(rb)
+ if err != nil {
+ if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
+ continue
+ }
+ log.Printf("ReadFrom failed: %v", err)
+ continue
+ }
+
+ rm, err := icmp.ParseMessage(ipv4.ICMPTypeEcho.Protocol(), rb[:n])
+ if err != nil {
+ log.Printf("ParseMessage failed: %v", err)
+ continue
+ }
+
+ switch rm.Type {
+ case ipv4.ICMPTypeEcho:
+ echoBody := rm.Body.(*icmp.Echo)
+ log.Printf("Received Echo Request from %v: ID=%d, Seq=%d",
+ peer, echoBody.ID, echoBody.Seq)
+
+ wm := icmp.Message{
+ Type: ipv4.ICMPTypeEchoReply, // Change type to Reply
+ Code: 0,
+ Body: &icmp.Echo{
+ ID: echoBody.ID,
+ Seq: echoBody.Seq,
+ Data: echoBody.Data,
+ },
+ }
+
+ wb, err := wm.Marshal(nil)
+ if err != nil {
+ log.Printf("Marshal failed: %v", err)
+ continue
+ }
- buf := make([]byte, 1024)
- numRead, _, _ := conn.ReadFrom(buf)
+ if _, err := conn.WriteTo(wb, peer); err != nil {
+ log.Printf("WriteTo failed: %v", err)
+ }
+ log.Printf("Sent Echo Reply to %v", peer)
- fmt.Printf("% X\n", buf[:numRead])
+ case ipv4.ICMPTypeEchoReply:
+ log.Printf("Received Echo Reply from %v", peer)
+ default:
+ log.Printf("Received unhandled ICMP message type %v from %v", rm.Type, peer)
+ }
+ }
}
| | |