Пример #1
0
func csum(b []byte) uint16 {
	// Make checksum
	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

	return netu.Htons(^uint16(s))
}
Пример #2
0
func main() {
	// Get app params from console args
	var err error
	Params, err = NewAppParams(os.Args[1:])
	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		return
	}
	// seed pseudo random generator; We'll need it later
	rand.Seed(time.Now().UnixNano())

	// Overwrite local only because my network is a bitch
	if localAddr := os.Getenv("GRNVS_TRACE6_LADDR"); localAddr != "" {
		fmt.Fprintf(os.Stderr, "Using %s as local ip address\n", localAddr)
		Params.LocalAddress, err = net.ResolveIPAddr("ip6", localAddr)
		if err != nil {
			panic(err)
		}
	}

	// Init raw socket for writing (IPPROTO_RAW is only for writing -> man 7 raw)
	connWrite = createConn(syscall.AF_INET6, syscall.IPPROTO_RAW)
	defer connWrite.Close()
	// Socket for reading
	sockRead, err = syscall.Socket(syscall.AF_PACKET, syscall.SOCK_DGRAM, int(netu.Htons(syscall.ETH_P_IPV6)))
	if err != nil {
		panic(err)
	}
	fileRead = os.NewFile(uintptr(sockRead), fmt.Sprintf("fd-sock-read-%d", sockRead))
	defer syscall.Close(sockRead)
	defer fileRead.Close()

	// Create the base package, IPv6-Header + ICMP6 Echo Request
	// Generate id for icmp package
	id := uint16(rand.Uint32())
	pck, l := icmp6.NewEchoRequest(id, 0)
	// craft request package
	req := &request{
		Header: ipv6.NewHeader(&Params.LocalAddress.IP, &Params.RemoteAddress.IP),
		Body:   pck,
	}
	// set some ipv6 header values
	req.Header.NextHeader = 0x3a
	req.Header.PayloadLen = l

	chanReply = make(chan *response, 1)

	// Start traceing
	//done := false
	seq := uint16(0)
	var resp *response
	for i := 1; i <= Params.MaxHops; i++ {
		// print current hop
		fmt.Printf("%d", i)
		// Send a package for each hop
		for j := 0; j < Params.Attempts; j++ {
			// get request data
			p := req.Marshal(i, seq)
			// Send icmp package
			connWrite.WriteTo(p, Params.RemoteAddress)
			// Wait for response
			resp, err = recvResponse(req, &Params.RemoteAddress.IP)
			if err != nil {
				fmt.Printf(err.Error())
				return
			}
			if resp.Timeout {
				fmt.Printf("  *")
			} else if resp.EchoReply || resp.TimeExceeded {
				fmt.Printf("  %s", resp.Sender.String())
			} else if resp.DestinationUnreachable {
				fmt.Printf("  %s!X", resp.Sender.String())
			}
			// increment sequence
			seq++
		}
		fmt.Print("\n")
		// stop if we are done
		if resp.EchoReply || resp.DestinationUnreachable {
			os.Exit(1) // Termination
		}
	}
}