1. 程式人生 > >[go]ipv6 ping測試

[go]ipv6 ping測試

其實很簡單.就是對照go原始碼的ipraw_test.go和之前的ping.go

改造一個ping6.go.變化很小

// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// taken from http://golang.org/src/pkg/net/ipraw_test.go

//20131204,嘗試改造支援ipv6

package ping6

import (
	"bytes"
	"errors"
	"net"
	"os"
	"time"
	"fmt"

)

const (
	icmpv4EchoRequest = 8
	icmpv4EchoReply   = 0
	icmpv6EchoRequest = 128
	icmpv6EchoReply   = 129
)

type icmpMessage struct {
	Type     int             // type
	Code     int             // code
	Checksum int             // checksum
	Body     icmpMessageBody // body
}

type icmpMessageBody interface {
	Len() int
	Marshal() ([]byte, error)
}

// Marshal returns the binary enconding of the ICMP echo request or
// reply message m.
func (m *icmpMessage) Marshal() ([]byte, error) {
	b := []byte{byte(m.Type), byte(m.Code), 0, 0}
	if m.Body != nil && m.Body.Len() != 0 {
		mb, err := m.Body.Marshal()
		if err != nil {
			return nil, err
		}
		b = append(b, mb...)
	}
	switch m.Type {
	case icmpv6EchoRequest, icmpv6EchoReply:
		return b, nil
	}
	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
	// Place checksum back in header; using ^= avoids the
	// assumption the checksum bytes are zero.
	b[2] ^= byte(^s & 0xff)
	b[3] ^= byte(^s >> 8)
	return b, nil
}

// parseICMPMessage parses b as an ICMP message.
func parseICMPMessage(b []byte) (*icmpMessage, error) {
	msglen := len(b)
	if msglen < 4 {
		return nil, errors.New("message too short")
	}
	m := &icmpMessage{Type: int(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
	if msglen > 4 {
		var err error
		switch m.Type {
		case icmpv4EchoRequest, icmpv4EchoReply, icmpv6EchoRequest, icmpv6EchoReply:
			m.Body, err = parseICMPEcho(b[4:])
			if err != nil {
				return nil, err
			}
		}
	}
	return m, nil
}

// imcpEcho represenets an ICMP echo request or reply message body.
type icmpEcho struct {
	ID   int    // identifier
	Seq  int    // sequence number
	Data []byte // data
}

func (p *icmpEcho) Len() int {
	if p == nil {
		return 0
	}
	return 4 + len(p.Data)
}

// Marshal returns the binary enconding of the ICMP echo request or
// reply message body p.
func (p *icmpEcho) Marshal() ([]byte, error) {
	b := make([]byte, 4+len(p.Data))
	b[0], b[1] = byte(p.ID>>8), byte(p.ID&0xff)
	b[2], b[3] = byte(p.Seq>>8), byte(p.Seq&0xff)
	copy(b[4:], p.Data)
	return b, nil
}

// parseICMPEcho parses b as an ICMP echo request or reply message body.
func parseICMPEcho(b []byte) (*icmpEcho, error) {
	bodylen := len(b)
	p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
	if bodylen > 4 {
		p.Data = make([]byte, bodylen-4)
		copy(p.Data, b[4:])
	}
	return p, nil
}

func Ping(address string, timeout int) (alive bool,err error,timedelay int64) {
  t1:=time.Now().UnixNano()
	err = Pinger(address, timeout)
	t2:=time.Now().UnixNano()
	alive = err == nil
	return alive,err,t2-t1
}

func Pinger(address string, timeout int) (err error) {
	//c, err := net.Dial("ip4:icmp", address)
	c, err := net.Dial("ip6:ipv6-icmp", address)
	if err != nil {
		fmt.Println("error ",err)
		return
	}
	

		
 
	c.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Millisecond))  //時延ms單位
	defer c.Close()

	//typ := icmpv4EchoRequest
	typ := icmpv6EchoRequest
	xid, xseq := os.Getpid()&0xffff, 1
	wb, err := (&icmpMessage{
		Type: typ, Code: 0,
		Body: &icmpEcho{
			ID: xid, Seq: xseq,
			Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
		},
	}).Marshal()
	if err != nil {
		return
	}
	if _, err = c.Write(wb); err != nil {
		return
	}
	var m *icmpMessage
	rb := make([]byte, 20+len(wb))
	for {
		if _, err = c.Read(rb); err != nil {
			return
		}
		
			//if net == "ip4" {  //only for ipv4
			//	rb = ipv4Payload(rb)
			//}
	
		
		if m, err = parseICMPMessage(rb); err != nil {
			return
		}
		switch m.Type {
		case icmpv4EchoRequest, icmpv6EchoRequest:
		  //fmt.Println("type ",m.Type)
			continue
		}
		break
	}
	return
}

func ipv4Payload(b []byte) []byte {
	if len(b) < 20 {
		return b
	}
	hdrlen := int(b[0]&0x0f) << 2
	fmt.Println("hdrlen ",hdrlen)   //ipv4的時候為20
	return b[hdrlen:]
}


測試程式

/*
測試一下icmpv6
*/
package main
import (
"ping6"
"fmt"
"time"
"os"
)

func main() {
	//1.輸入引數處理.這裡使用os而非flag
	var host string
	if len(os.Args) != 2 {
		//fmt.Println("Usage: ", os.Args[0], "host")
		host="::1"
		//os.Exit(1)
	}else{
	  host = os.Args[1]   //目標域名
  }
  
 t1:=time.Now().UnixNano()
 
 alive,err,timedelay:=ping6.Ping(host,1000)
 fmt.Println("result ",alive,err,timedelay)
 t2:=time.Now().UnixNano()
 fmt.Println(t2-t1);
 
}

相關推薦

[go]ipv6 ping測試

其實很簡單.就是對照go原始碼的ipraw_test.go和之前的ping.go 改造一個ping6.go.變化很小 // Copyright 2009 The Go Authors. All rights reserved. // Use of this source

[go]go版的ping測試程式(1)

在<Go語言程式設計>中有icmp ping的例子,不過實際測試不通過....這個有空研究一下原始碼再看.  注: 原文程式碼需要修改 _, err = conn.Read(msg[0:]) 改為_, err = conn.Read(msg[20:]) 在網找

mac本地如何搭建IPv6環境測試你的APP

和我 別了 開啟 飛行模式 服務器 後者 系統偏好設置 解決辦法 出現 轉自:http://www.cocoachina.com/ios/20160525/16431.html 投稿文章,作者:請勺子喝杯咖啡(簡書) IPv6的簡介 IPv4 和 IPv6的區別就是 IP

ping測試某網段網絡連通性

ash done line then -c seq off 8.14 don ping測試某網段網絡連通性 #!/bin/bash for i in `seq 1 14`;do ping 100.88.14.$i -c 2 >/dev/null if [

家庭寬頻之IPv6網路測試

之前總感覺IPv6距離我們很遠,然而它卻在悄無生息中走進我們的網路世界,之前有朋友說青島的家庭寬頻已經支援IPv6了,喲……那我們這裡呢? 我的家庭寬頻是聯通的,通過命令檢視本機獲取的IP地址,發現如下: 通過命令可以看到電腦的確獲取了IPv6地址。 通過https://test-ipv6.co

記一次Node和Go的效能測試

以前簡單測過go的效能,高併發場景下確實比node會好一些,一直想找個時間系統性地測一下,手頭正好有一臺前段時間買的遊戲主機,裝了ubuntu就開測了 準備工作 測試機和試壓機系統都是ubuntu 18.04.1 首先安裝node和go,版本分別如下: node 10.13.0

ping---測試主機之間網路的連通性

ping命令用來測試主機之間網路的連通性。執行ping指令會使用ICMP傳輸協議,發出要求迴應的資訊,若遠端主機的網路功能沒有問題,就會迴應該資訊,因而得知該主機運作正常。   選項 -d:使用Socket的SO_DEBUG功能; -c<完成次數>:設定完成要求迴應的次數; -f:

go之單元測試

cal.go package testcase func sum(n int) int{ sum := 0 for i:=1;i<=n;i++{ sum += i } return sum } func sub(a,b int)int{ return a -b }   

Go 語言單元測試

go 語言發展非常迅速,大家對go語言程式設計也比較熟悉了,但很多同學對於go語言的測試不太熟悉,最近準備三篇關於Go語言的測試文章來介紹Go語言的測試相關內容。 單元測試框架 go語言提供了編寫go語言的自動化測試框架testing.T,tes

Go的自動化測試

自動化測試,是在預設條件下執行系統或應用程式,評估執行結果,預先條件包括正常條件和異常條件。Go本身提供了一套輕量級的測試框架,相對低階,但不過還是有效的。它依賴一個go test測試命令,和一組按照約定方式編寫的測試函式,符合規則的測試程式碼會在執行測試時被自

[原始碼和文件分享]基於java語言的FTP伺服器(Ping測試工具軟體)

一 需求分析 已知引數:目的節點IP地址或主機名 設計要求:通過原始套接字程式設計,模擬Ping命令,實現其基本功能,即輸入一個IP地址或一段IP地址的範圍,分別測試其中每個IP地址所對應主機的可達性,並返回耗時、生存時間等引數,並統計成功傳送和回送的Ping報文

Go小爬蟲測試

package main import ( "fmt" "io/ioutil" "log" "net/http" ) type ThreadItem struct { url string content string imgs []string } func http

IPv6 MLD測試環境搭建

簡要描述IP v6 MLD_proxy和MLD_snooping的功能定義及測試環境搭建過程 一、MLD的含義 MLD 是Multicast Listener Discovery Protocol(組播偵聽者發現協議)的簡稱,它用於IPv6 路由器在其直連網段上發現組播偵聽者。 組播偵聽

提升iOS稽核通過率之“IPv6相容測試

作者:jingle 騰訊系統測試工程師 商業轉載請聯絡騰訊WeTest授權,非商業轉載請註明出處。 一、背景 在WWDC2015大會上蘋果宣佈iOS9將支援純IPv6的網路服務。2016年6月1號,所有提交到AppStore上的應用都必須支

GO Test 單元測試&壓力測試

背景 本文主要介紹golang的一個工具go test Go語言中自帶有一個輕量級的測試框架testing和自帶的go test命令來實現單元測試和效能測試,testing框架和其他語言中的測試框架類似,你可以基於這個框架寫針對相應函式的測試用例,也可以基於

【指南】本地如何搭建IPv6環境測試你的APP

原文地址:http://www.cocoachina.com/ios/20160525/16431.html 投稿文章,作者:請勺子喝杯咖啡(簡書) IPv6的簡介 IPv4 和 IPv6的區別就是 IP 地址前者是 .(dot)分割,後者是以 :(冒號)分割

shell下用ping 測試一個網路是否通,只顯示結果而不顯示過程輸出

要求:用ping 測試一個網址但只顯示是否通而不顯示過程輸出 if [ "`ping -c 1 A.B.C.D `" ]; then echo yes && exit 0 else echo no && exit 0 fi

java 中 呼叫ping測試網路是否通

public static final String[] encodes = new String[] { "UTF-8", "GBK", "GB2312", "ISO-8859-1", "ISO-8859-2" };public static void main(Stri

Go語言HTTP測試及程式效能調優

         這篇要講的東西,主要是HTTP,WebSocket的測試及如何調優Go程式的一些方法. 分下面幾個內容: 一.httptest測試包 二.效能測試 三.怎麼利用引數分析和調優程式四.在執行中實時監控調優 一.httptest測試包 對於HTTP和WebS

Linux ping --測試與目標主機的連通性

Linux系統的ping命令是常用的網路命令,它通常用來測試與目標主機的連通性,我們經常會說“ping一下某機器,看是不是開著”、不能開啟網頁時會說“你先ping閘道器地址192.168.1.1試試”。它通過傳送ICMP ECHO_REQUEST資料包到網路主機 (send ICMP ECHO_REQUES