用Golang自己构造ICMP数据包

用Golang自己构造ICMP数据包

ICMP是用来对网络状况进行反馈的协议,可以用来侦测网络状态或检测网路错误。

限于当前Golang在网络编程方面的代码稀缺,资料甚少,所以分享一个用Golang来构造ICMP数据包并发送ping程序的echo消息的实例。

RFC定义的echo数据包结构:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type

Code

Checksum

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Identifier

SequenceNumber

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Data...+-+-+-+-+-

代码:

packagemainimport(  "bytes"  "encoding/binary"  "fmt"  "net")typeICMPstruct{  Typeuint8  Codeuint8  Checksumuint16  Identifieruint16  SequenceNumuint16}funcCheckSum(data[]byte)uint16{  var(    sumuint32    lengthint=len(data)    indexint  )  forlength1{    sum+=uint32(data[index])8+uint32(data[index+1])    index+=2    length-=2  }  iflength0{    sum+=uint32(data[index])  }  sum+=(sum16)  returnuint16(^sum)}funcmain(){  var(    icmpICMP    laddrnet.IPAddr=net.IPAddr{IP:net.ParseIP("...")}//***IP地址改成你自己的网段***    raddrnet.IPAddr=net.IPAddr{IP:net.ParseIP("...1")}  )  //如果你要使用网络层的其他协议还可以设置成ip:ospf、ip:arp等  conn,err:=net.DialIP("ip4:icmp",laddr,raddr)  iferr!=nil{    fmt.Println(err.Error())    return  }  deferconn.Close()  //开始填充数据包  icmp.Type=8//8-echomessage0-replymessage  icmp.Code=0  icmp.Checksum=0  icmp.Identifier=0  icmp.SequenceNum=0  var(    bufferbytes.Buffer  )  //先在buffer中写入icmp数据报求去校验和  binary.Write(buffer,binary.BigEndian,icmp)  icmp.Checksum=CheckSum(buffer.Bytes())  //然后清空buffer并把求完校验和的icmp数据报写入其中准备发送  buffer.Reset()  binary.Write(buffer,binary.BigEndian,icmp)  if_,err:=conn.Write(buffer.Bytes());err!=nil{    fmt.Println(err.Error())    return  }  fmt.Printf("sendicmppacketsuccess!")}

执行后可以用wireshark抓下包看看,可以看到远方网关传来了reply响应:

看看我们构造的ICMP是否正确:

如果转载请注明出处:







































白癜风怎样治疗最快
白癜风是否传染



转载请注明:http://www.92nongye.com/gaishu/gaishu/204612515.html

  • 上一篇文章:
  •   
  • 下一篇文章: