Go 实现 Ping命令,

本文介绍了一个自定义的Ping命令实现,支持并发操作、伪造发送者的IP地址,并能定制数据包大小和发送次数。通过直接构造ICMP包并携带数据,展示了在网络诊断和测试中灵活应用Ping命令的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

怎么说呢

这也不是一个完整的Ping过程处理,

更像是一个可以测试Ping服务器的工具。

支持并发,编译完后,可以用ping.exe -help 查看使用说明

上代码吧,

 

/**
 * 邪恶的Ping命令,
 * 只发数据报,不接收,而且可以伪造别人的IP
 */
package main

import (
	"bytes"
	"flag"
	"fmt"
	"net"
	"time"
        "runtime"
)

var (
	datalen    int    = 100
	timeout    int    = 10
	targethost string = "www.XXXXX.com"
	localIp    string = "102.23.24.5.135"
	times      int    = 10
	concurrent int    = 10 //10个并发
)

func doPing(laddr *net.IPAddr, raddr *net.IPAddr, b *[]byte) {
	defer func() {
		tmp <- true
	}()
	conn, err := net.DialIP("ip4:icmp", laddr, raddr)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
	_, err = conn.Write(*b)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer conn.Close()
}

var tmp chan bool

func main() {

	flag.StringVar(&targethost, "target", "www.baidu.com", "目标地址")
	flag.StringVar(&localIp, "local", "102.23.24.5.135", "发送源地址")
	flag.IntVar(&timeout, "timeout", 10, "超时设置,单位秒")
	flag.IntVar(&datalen, "datalen", 1024, "携带数据包大小")
	flag.IntVar(&times, "times", 1, "Ping次数")
	flag.IntVar(&concurrent, "concurrent", 1, "并发数,不能小于Ping次数")
	flag.Parse()
	fmt.Printf("Ping %s\n发送方IP:%s\n,数据长度:%d\n超时:%d秒\n发送次数:%d\n并发数:%d\n", targethost, localIp, datalen, timeout, times, concurrent)
	tmp = make(chan bool, concurrent)
        runtime.GOMAXPROCS(runtime.NumCPU())
	var (
		laddr    = net.IPAddr{IP: net.ParseIP(localIp)}
		raddr, _ = net.ResolveIPAddr("ip", targethost)
	)
	//直接构造ICMP包,带数据的
	b := []byte{8, 0, 0, 0}
	b = append(b, bytes.Repeat([]byte("a"), datalen)...)
	csumcv := len(b) - 1 // checksum coverage
	s := uint32(0)
	for i := 0; i < csumcv; i += 2 {
		s += uint32(b[i+1])<<8 | uint32(b[i])
	}
	if csumcv&1 == 0 {
		s += uint32(b[csumcv])
	}
	s = s>>16 + s&0xffff
	s = s + s>>16
	b[2] ^= byte(^s & 0xff)
	b[3] ^= byte(^s >> 8)

	start := time.Now()
	//使用并发
	for i := 0; i < concurrent; i++ {
		go doPing(&laddr, raddr, &b)
	}
	for i := 0; i < times; i++ {
		<-tmp
		if i < times-concurrent {
			go doPing(&laddr, raddr, &b)
		}
		fmt.Print(".")
	}
	sub := time.Now().Sub(start) / 1e6
	fmt.Println()
	fmt.Printf("全部请求发送完成,耗时:%d毫秒", sub)
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值