int MDDSocket_Init(void)
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        LOG_ERROR("MDDSocket, WSAStartup failed with error: %d\n", err);
        return MDD_ERROR;
    }

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        LOG_ERROR("MDDSocket, Could not find a usable version of Winsock.dll\n");
        WSACleanup();
        return MDD_ERROR;
    }

    sendMsgSocket = socket(AF_INET,SOCK_DGRAM,0);
    if (sendMsgSocket == INVALID_SOCKET)
    {
        LOG_ERROR("MDDSocket,socket function failed when create socket for sendMsg with error = %d\n", WSAGetLastError() );
        return MDD_ERROR;
    }

    if (NULL == (fpWSASendMsg = GetWSASendMsgFunctionPointer(sendMsgSocket)))
    {
        LOG_ERROR("GetWSASendMsgFunctionPointer returns null pointer.\n");
        return MDD_ERROR;
    }

    recvMsgSocket = socket(AF_INET,SOCK_DGRAM,0);
    if (recvMsgSocket == INVALID_SOCKET)
    {
        LOG_ERROR("MDDSocket,socket function failed when create socket for recvMsg with error = %d\n", WSAGetLastError() );
        return MDD_ERROR;
    }

    if (NULL == (fpWSARecvMsg = GetWSARecvMsgFunctionPointer(recvMsgSocket)))
    {
        LOG_ERROR("GetWSARecvMsgFunctionPointer returns null pointer.\n");
        return MDD_ERROR;
    }

    return MDD_OK;
}
Пример #2
0
int __cdecl main()
{
    WSADATA             wsd;
    INT                 i = 0,
                        nErr = 0,
                        nStartup = 0,
                        rc = 0;
    SOCKET              sock = INVALID_SOCKET;
    SOCKADDR_STORAGE    addr = {0},
                        mcaddr = {0},
                        remoteaddr = {0};
    WSAOVERLAPPED       over = {0};
    WSABUF              wsabuf = {0};
    DWORD               dwBytes = 0,
                        dwFlags = 0,
                        dwRet = 0;
    IPV6_MREQ           mreq = {0};
    WSAMSG              wsamsg = {0};
    LPFN_WSARECVMSG     WSARecvMsg = NULL;


    __try
    {
        //Initialize Winsock

        nErr = WSAStartup(WS_VER,&wsd);
        if (nErr)
        {
            WSASetLastError(nErr);
            ERR("WSAStartup");
            __leave;
        }
        else
            nStartup++;


        // bind socket and register multicast

        mcaddr.ss_family = AF_INET6;

        InitMcastAddr((SOCKADDR*)&mcaddr,sizeof mcaddr);

        if (INVALID_SOCKET == (sock = socket(AF_INET6,SOCK_DGRAM,0)))
        {
            ERR("socket");
            __leave;
        }

        if(!RouteLookup((SOCKADDR*)&mcaddr,
                        sizeof mcaddr,
                        (SOCKADDR*)&addr,
                        sizeof addr
                       ))
        {
            ERR("RouteLookup");
            __leave;
        }

        SET_PORT((SOCKADDR*)&addr,DEFAULT_PORT);

        if (SOCKET_ERROR == bind(sock,(SOCKADDR*)&addr,sizeof addr))
        {
            ERR("bind");
            __leave;
        }

        mreq.ipv6mr_multiaddr = ((SOCKADDR_IN6*)&mcaddr)->sin6_addr;

        if (SOCKET_ERROR == setsockopt(sock,
                                       IPPROTO_IPV6,
                                       IPV6_ADD_MEMBERSHIP,
                                       (char*)&mreq,
                                       sizeof mreq
                                      ))
        {
            ERR("setsockopt IPV6_ADD_MEMBRESHIP");
            __leave;
        }

        // PktInfo

        if (!SetIpv6PktInfoOption(sock))
        {
            ERR("SetIpv6PktInfoOption");
            __leave;
        }

        if(!AllocAndInitIpv6PktInfo(&wsamsg))
        {
            ERR("AllocAndInitIpv6PktInfo");
            __leave;
        }

        // data buffer

        wsabuf.buf = (CHAR*)MALLOC(100);

        if(NULL == wsabuf.buf)
        {
            ERR("HeapAlloc");
            __leave;
        }

        wsabuf.len = (ULONG)MSIZE(wsabuf.buf);
        wsamsg.lpBuffers = &wsabuf;
        wsamsg.dwBufferCount = 1;

        // packet source address
        wsamsg.name = (SOCKADDR*)&remoteaddr;
        wsamsg.namelen = sizeof remoteaddr;

        //Post overlapped WSARecvMsg
        InitOverlap(&over);

        if (NULL == (WSARecvMsg = GetWSARecvMsgFunctionPointer()))
        {
            ERR("GetWSARecvMsgFunctionPointer");
            __leave;
        }

        if (SOCKET_ERROR == WSARecvMsg(sock,
                                       &wsamsg,
                                       &dwBytes,
                                       &over,
                                       NULL
                                      ))
        {
            if (WSA_IO_PENDING != WSAGetLastError())
            {
                ERR("WSARecvMsg");
                __leave;
            }
        }

        //set send interface

        if (SOCKET_ERROR == SetSendInterface(sock,(SOCKADDR*)&addr))
        {
            ERR("SetSendInterface");
            __leave;
        }

        //send msg to multicast


        SET_PORT((SOCKADDR*)&mcaddr,DEFAULT_PORT);

        //send a few packets
        for (i=0; i<5; i++)
        {

            if (SOCKET_ERROR == (rc = sendto(sock,
                                             TST_MSG,
                                             lstrlenA(TST_MSG),
                                             0,
                                             (SOCKADDR*)&mcaddr,
                                             sizeof (mcaddr)
                                            )))
            {
                ERR("sendto");
                __leave;
            }

            printf("Sent %d bytes\n",rc);
        }

        dwRet = WaitForSingleObject(over.hEvent,DEFAULT_WAIT);

        if (dwRet)
        {
            printf("%s\n",gai_strerror(dwRet));
            __leave;
        }

        if (!WSAGetOverlappedResult(sock,
                                    &over,
                                    &dwBytes,
                                    TRUE,
                                    &dwFlags
                                   ))
        {
            ERR("WSAGetOverlappedResult");
            __leave;
        }

        printf("WSARecvMsg completed with %d bytes\n",dwBytes);

        // if multicast packet do further processing
        if (MSG_MCAST & wsamsg.dwFlags)
        {
            if (ProcessIpv6Msg(&wsamsg))
            {
                //do something more interesting here
                printf("Recvd multicast msg.\n");
            }

        }

    }
    __finally
    {


        CLOSESOCK(sock);
        FREE(wsabuf.buf);
        FREE(wsamsg.Control.buf);
        CLOSESOCKEVENT(over.hEvent);
        if(nStartup) WSACleanup();
    }

    return 0;
}