Skip to content

Commit

Permalink
FIX : large IP crash
Browse files Browse the repository at this point in the history
  • Loading branch information
unshade committed Mar 26, 2024
1 parent 762462f commit e3480ae
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 73 deletions.
75 changes: 2 additions & 73 deletions internal/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package internal

import (
"fmt"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"net"
"os"
"strings"
"time"
)
Expand Down Expand Up @@ -54,10 +51,7 @@ func ScanGatewayNetwork(gateway net.IPNet) string {
builder.WriteString(fmt.Sprintf("Broadcast: %s\n", broadcast.String()))
builder.WriteString("Mask: " + mask.String() + "\n")

n := 1
for i := 0; i < len(mask); i++ {
n *= 256 - int(mask[i])
}
n := 255

channels := make([]chan string, n)

Expand All @@ -78,7 +72,7 @@ func ScanGatewayNetwork(gateway net.IPNet) string {
}

c := 0
for ip := network.Mask(mask); !ip.Equal(broadcast); incIP(ip) {
for ip := network.Mask(mask); !ip.Equal(broadcast); IncIP(ip) {
if !ip.Equal(network) && !ip.Equal(broadcast) {
channels[c%n] <- ip.String()
c++
Expand All @@ -91,68 +85,3 @@ func ScanGatewayNetwork(gateway net.IPNet) string {

return builder.String()
}

func Ping(ipString string, timeout time.Duration) (time.Duration, error) {
c, err := icmp.ListenPacket("udp4", "0.0.0.0")
if err != nil {
return 0, err
}
defer c.Close()
// Generate an Echo message
msg := &icmp.Message{
Type: ipv4.ICMPTypeEcho,
Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff,
Seq: 1,
Data: []byte("Hello, are you there!"),
},
}
wb, err := msg.Marshal(nil)
if err != nil {
return 0, err
}
// Send, note that here it must be a UDP address
start := time.Now()
if _, err := c.WriteTo(wb, &net.UDPAddr{IP: net.ParseIP(ipString)}); err != nil {
return 0, err
}
// Read the reply package
reply := make([]byte, 1500)
err = c.SetReadDeadline(time.Now().Add(timeout))
if err != nil {
return 0, err
}
n, peer, err := c.ReadFrom(reply)
if err != nil {
return 0, err
}
duration := time.Since(start)

// The reply packet is an ICMP message, parsed first
msg, err = icmp.ParseMessage(1, reply[:n])
if err != nil {
return 0, err
}

// Get results
if msg.Type == ipv4.ICMPTypeEchoReply {
echoReply, ok := msg.Body.(*icmp.Echo) // The message body is of type Echo
if !ok {
return 0, fmt.Errorf("invalid ICMP Echo Reply message")
}
if peer.(*net.UDPAddr).IP.String() == ipString && echoReply.Seq == 1 && echoReply.ID == os.Getpid()&0xffff {
return duration, nil
}
}
return 0, fmt.Errorf("unexpected ICMP message type: %v", msg.Type)
}

func incIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
71 changes: 71 additions & 0 deletions internal/ip.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package internal

import (
"fmt"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"net"
"os"
"regexp"
"strconv"
"time"
)

func IsValidIP(ip string) bool {
Expand All @@ -17,3 +23,68 @@ func IsValidPort(port string) bool {
}
return i > 0 && i < 65536
}

func IncIP(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}

func Ping(ipString string, timeout time.Duration) (time.Duration, error) {
c, err := icmp.ListenPacket("udp4", "0.0.0.0")
if err != nil {
return 0, err
}
defer c.Close()
// Generate an Echo message
msg := &icmp.Message{
Type: ipv4.ICMPTypeEcho,
Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff,
Seq: 1,
Data: []byte("Hello, are you there!"),
},
}
wb, err := msg.Marshal(nil)
if err != nil {
return 0, err
}
// Send, note that here it must be a UDP address
start := time.Now()
if _, err := c.WriteTo(wb, &net.UDPAddr{IP: net.ParseIP(ipString)}); err != nil {
return 0, err
}
// Read the reply package
reply := make([]byte, 1500)
err = c.SetReadDeadline(time.Now().Add(timeout))
if err != nil {
return 0, err
}
n, peer, err := c.ReadFrom(reply)
if err != nil {
return 0, err
}
duration := time.Since(start)

// The reply packet is an ICMP message, parsed first
msg, err = icmp.ParseMessage(1, reply[:n])
if err != nil {
return 0, err
}

// Get results
if msg.Type == ipv4.ICMPTypeEchoReply {
echoReply, ok := msg.Body.(*icmp.Echo) // The message body is of type Echo
if !ok {
return 0, fmt.Errorf("invalid ICMP Echo Reply message")
}
if peer.(*net.UDPAddr).IP.String() == ipString && echoReply.Seq == 1 && echoReply.ID == os.Getpid()&0xffff {
return duration, nil
}
}
return 0, fmt.Errorf("unexpected ICMP message type: %v", msg.Type)
}

0 comments on commit e3480ae

Please sign in to comment.