Thread: IPv6 ping in windows...problem..lots of ode:(

  1. #1
    Neill KElly

    Question IPv6 ping in windows...problem..lots of ode:(


    I am converting a ping program from ipv4 to ipv6.

    My problem is, the program doesn't send the echo request.

    I have a feeling that it may be to do with the parameters i am passing to the function, or something to do with the structures and pointers.

    The program compiles, runs, resolves the addresses, but will not actually send the echo request.

    I am sorry for posting all the code, but i am desprate and need pointing in the right direction.

    My head is about to explode!!!

    My header file ping.h is included below the main code.

    Thank you to anyone who can help

    // PING6.C -- Ping program using ICMP and RAW Sockets
    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <winnt.h>
    #include "ping6.h"
    #include <tpipv6.h>
    #include <Ws2tcpip.h>
    #include "inet_ntop.c"
    #include "inet_pton.h"
    //Internal Functions
    void Ping(const char *com_line_host);
    int  WaitForEchoReply(SOCKET s);
    // ICMP Echo Request/Reply functions
    int		SendEchoRequest(SOCKET, LPSOCKADDR_IN6);
    //const char *com_line_host;
    // main()
    void main(int argc, char **argv)
    	WSADATA wsaData;
        WORD wVersionRequested = MAKEWORD(2,0);
        int nRet;
    	argv[1] = "";
    	// Init WinSock
        nRet = WSAStartup(wVersionRequested, &wsaData);
        if (nRet)
    		fprintf(stderr,"\nError initializing WinSock\n");
    	// Check version
    	if (wsaData.wVersion != wVersionRequested)
    		fprintf(stderr,"\nWinSock version not supported\n");
    	// Go do the ping
    	// Free WinSock
    // Ping()
    // Calls SendEchoRequest() and
    // RecvEchoReply() and prints results
    void Ping(const char *com_line_host)
    	SOCKET	  rawSocket;
    	//LPHOSTENT lpHost;
    	struct    sockaddr_in6 saDest, saSrc;
    	struct    addrinfo hints, *res, *res0;
    	DWORD	  dwTimeSent;
    	DWORD	  dwElapsed;
    	int       nLoop;
    	int       nRet;
    	int		  error;
    	char buf[56];
    	rawSocket = socket(AF_INET6, SOCK_RAW, 58);
    	if (rawSocket == SOCKET_ERROR)
    		printf("error creating Socket");
    	memset(&hints, 0, sizeof(hints));
    	memset(&res0, 0, sizeof(res0));
    	hints.ai_flags = AI_CANONNAME;
    	error = getaddrinfo(com_line_host, NULL, &hints, &res0);
    	if (error) {
    	    printf("%s", gai_strerror(error));
    	// Create raw ipv6 Socket 
    	rawSocket = socket(AF_INET6, SOCK_RAW, 58); //58 = icmpv6
    	if (rawSocket == SOCKET_ERROR)
    		printf("error creating Socket");
    	// Setup destination address
    	saDest.sin6_addr = (((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr);
    	saDest.sin6_family = AF_INET6;
    	saDest.sin6_port = 0;
    	// Tell the user what we're doing
    	printf("\nPinging %s [%s] with %d bytes of data:\n",
    				inet_ntop(AF_INET6,&saDest.sin6_addr, buf, sizeof(buf)),
    	// Ping multiple times
    	for (nLoop = 0; nLoop < 4; nLoop++)
    		// Send ICMP echo request
    		SendEchoRequest(rawSocket, &saDest);
    		// Use select() to wait for data to be received
    		nRet = WaitForEchoReply(rawSocket);
    		if (nRet == SOCKET_ERROR)
    			printf ("select()"); 
    		if (!nRet)
    		// Receive reply
    		dwTimeSent = RecvEchoReply(rawSocket, &saSrc);
    		// Calculate elapsed time
    		dwElapsed = GetTickCount() - dwTimeSent;
    		printf("\nReply from: %s: bytes=%d time=%ldms", 
                   inet_ntop(AF_INET6,&saDest.sin6_addr, buf, sizeof(buf)), 
    	nRet = closesocket(rawSocket);
    	if (nRet == SOCKET_ERROR)
    // SendEchoRequest()
    // Fill in echo request header
    // and send to destination
    int SendEchoRequest(SOCKET s,LPSOCKADDR_IN6 lpstToAddr) 
    	static ECHOREQUEST echoReq;
    	static nId = 1;
    	static nSeq = 1;
    	int nRet, error;
    	// Fill in echo request
    	echoReq.icmp6Hdr.icmp6_type		= 128;
    	echoReq.icmp6Hdr.icmp6_code		= 0;
    	echoReq.icmp6Hdr.icmp6_cksum	= 0;
    	echoReq.icmp6Hdr.icmp6_id			= nId++;
    	echoReq.icmp6Hdr.icmp6_seq			= nSeq++;
    	// Fill in some data to send
    	for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
    		echoReq.cData[nRet] = ' '+nRet;
    	// Save tick count when sent
    	echoReq.dwTime				= GetTickCount();
    	// Send the echo request  								  
    	nRet = sendto(s,						/* socket */
    				 (LPSTR)&echoReq,			/* buffer */
    				 sizeof(ECHOREQUEST),		// buffer size
    				 0,							/* flags */
    				 (LPSOCKADDR)lpstToAddr, /* destination */
    				 sizeof(SOCKADDR_IN6));   /* address length */
    	error = WSAGetLastError();
    	if (nRet == SOCKET_ERROR) 
    		printf ("\nData not Sent");
    	return (nRet);
    // RecvEchoReply()
    // Receive incoming data
    // and parse out fields
    DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN6 lpsaFrom) 
    	ECHOREPLY echoReply;
    	int nRet;
    	int nAddrLen = sizeof(struct sockaddr_in6);
    	int error;
    	// Receive the echo reply	
    	nRet = recvfrom(s,					// socket
    					(LPSTR)&echoReply,	// buffer
    					sizeof(ECHOREPLY),	// size of buffer
    					0,					// flags
    					(LPSOCKADDR)lpsaFrom,	// From address
    					&nAddrLen);			// pointer to address len
    	// Check return value
    	if (nRet == SOCKET_ERROR) 
    		printf("\nNo Data Received");
    	error = WSAGetLastError();
    // WaitForEchoReply()
    // Use select() to determine when
    // data is waiting to be read
    int WaitForEchoReply(SOCKET s)
    	struct timeval Timeout;
    	fd_set readfds;
    	readfds.fd_count = 1;
    	readfds.fd_array[0] = s;
    	Timeout.tv_sec = 5;
        Timeout.tv_usec = 0;
    	return(select(1, &readfds, NULL, NULL, &Timeout));
    Ping.h Header File
    // Ping.h
    #pragma pack(1)
    #define ICMP_ECHOREPLY	129
    #define ICMP_ECHOREQ	128
    #include <Ws2tcpip.h>
    #include <winsock2.h>
    #include <Ws2tcpip.h>
    #include <tpipv6.h>
    #include <winnt.h>
    typedef struct icmp6_hdr {
         unsigned char     icmp6_type;   /* type field */
         unsigned char     icmp6_code;   /* code field */
         unsigned short    icmp6_cksum;  /* checksum field */
         unsigned short icmp6_id    ;  /* echo request/reply */
         unsigned short icmp6_seq   ;      /* echo request/reply */  
    #define REQ_DATASIZE 32		// Echo Request Data size
    // ICMP Echo Request
    typedef struct tagECHOREQUEST
    	ICMP6HDR icmp6Hdr;
    	DWORD	dwTime;
    	char	cData[REQ_DATASIZE];
    // ICMP Echo Reply
    typedef struct tagECHOREPLY
    	ECHOREQUEST	echoRequest;
    	char    cFiller[256];
    #pragma pack()

  2. #2
    Neill KElly
    i am running XP with ipv6 installed

    i can ping ipv6 addresses, and get to ipv6 websites



  3. #3
    Registered User
    Join Date
    Apr 2009
    Hi Neil,
    I am also facing issue in ping or traceroute programatically on Win XP and Win 2K3 platforms on IPv6 environment using raw sockets. On IPv4 environment, both ping and traceroute works fine in Vista / Non Vista (Win XP, Win 2003). But on IPv6 environment, both ping and tracroute are working fine only on Vista and not working on Windows XP or Windows 2003. We tried with ethereal and captured all the packets that are being send during ping. It says that "checksum incorrect " in the ping request. When gone through ICMPv6 RFC, they mentioned that checksum has to be calculated along with Pseudo-header. We included pseudo-header based on the information provided on sites, that didn't worked. We tried various options on pseudo header by including and not including source address, destination address. But nothing works. Kindly note that ping and traceroute are working fine from command line using ping and tracert on Win XP / Win 2003 in IPv6 environment.
    Have you got any solution for this problem? Please help me on this as this is a very critical issue in our project. Also let me know if you need more info.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Waterloo, Texas
    Why are you are responding to a 6 year old post?
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
        return std::pow
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  2. Windows 2000 Problem
    By DISGUISED in forum A Brief History of
    Replies: 13
    Last Post: 12-19-2001, 09:43 PM
  3. Windows XP Pro Problem!
    By oskilian in forum A Brief History of
    Replies: 10
    Last Post: 11-30-2001, 11:12 PM
  4. SDI Menu problem - Windows MSVC 6.0
    By Brown Drake in forum C++ Programming
    Replies: 0
    Last Post: 10-13-2001, 06:04 AM
  5. Problem with Borland 5.5 Compiling Windows Programs
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 08-28-2001, 09:04 AM