SOL9 2.0 Class: IcmpV6File

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * IcmpV6File.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL9
// 2010/10/31

#pragma once
#include <sol/Object.h>
#include <sol/Exception.h>
#include <sol/icmp/IcmpV6EchoReply.h>

/*
typedef struct {
    unsigned char Ttl;                         // Time To Live
    unsigned char Tos;                         // Type Of Service
    unsigned char Flags;                       // IP header flags
    unsigned char OptionsSize;                 // Size in bytes of options data
    unsigned char *OptionsData;                // Pointer to options data
} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
*/

namespace SOL {

class IcmpV6File :public Object {
private:
    HANDLE hIcmp;

public:
    IcmpV6File()
    :hIcmp(NULL)
    {
        this->hIcmp = Icmp6CreateFile();
    
        if (hIcmp == INVALID_HANDLE_VALUE) {
            throw Exception("Invalid handle.");
        }
    }
public:
    ~IcmpV6File()
    {
        if (hIcmp) {
            IcmpCloseHandle(hIcmp);
            hIcmp = NULL;
        }
    }

public:
    DWORD sendEcho2(
        __in const char* destinationAddress, // IPV6Address String. For example, Specify a string "::1" for localhost
        __in const char* requestData,
        __in PIP_OPTION_INFORMATION requestOptions, 
        __out IcmpV6EchoReply& echoReply,

        __in_opt   HANDLE event=NULL,
#ifdef PIO_APC_ROUTINE_DEFINED
        __in_opt PIO_APC_ROUTINE apcRoutine=NULL,
#else
        __in_opt FARPROC apcRoutine=NULL,
#endif
        __in   PVOID apcContext=NULL,
        __in   DWORD timeout=1000)
    {
        if (destinationAddress == NULL || requestData==NULL) {
            throw Exception("Invalid parameter");
        }

        //Source address
        sockaddr_in6 sourceSockAddr;
        memset(&sourceSockAddr, 0, sizeof(sourceSockAddr));
        sourceSockAddr.sin6_addr   = in6addr_any;
        sourceSockAddr.sin6_family = AF_INET6;

        //Get destination address
        addrinfo *destAddrInfo = NULL;
        addrinfo hints;
        memset(&hints, 0, sizeof(hints));
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_family   = AF_INET6;
        int ai_err = getaddrinfo(destinationAddress, 0, &hints, &destAddrInfo);
        if (ai_err) {
            throw Exception(gai_strerror(ai_err));            
        }

        sockaddr_in6 destSockAddr;
        memset(&destSockAddr, 0, sizeof(destSockAddr));
        destSockAddr.sin6_addr = ((sockaddr_in6 *)destAddrInfo->ai_addr)->sin6_addr;
        destSockAddr.sin6_family = AF_INET6;
        destSockAddr.sin6_port = 0;

        DWORD replySize = 0;
        DWORD requestSize = strlen(requestData) + 1;

        void* replyBuffer = echoReply.alloc(requestSize, replySize);

        DWORD rc = Icmp6SendEcho2(
                hIcmp,
                event,
                apcRoutine,
                apcContext,
                &sourceSockAddr,
                &destSockAddr, 
                (void*)requestData,
                requestSize,
                requestOptions,
                replyBuffer,
                replySize,
                timeout);

        freeaddrinfo(destAddrInfo);


        if (event !=NULL && apcRoutine !=NULL && apcContext !=NULL) {
            //async
            if (rc !=ERROR_IO_PENDING ) {
                throw GetLastError();
            }
        } else {
            //sync
            if (rc ==0) {
                throw GetLastError();
            }
        }

        return rc;
    }
};

}

Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.