< IP_TOS & SIO_ADDRESS_LIST_QUERY Examples | Socket Options & IOCTLs Main | SIO_GET_BROADCAST_ADDRESS & SO_KEEPALIVE_VALS Examples >


 

 

Socket Options and IOCTLs 7 part 6

 

 

What do we have in this chapter 7 part 6?

  1. Setting the IOCTL SIO_ENABLE_CIRCULAR_QUEUEING Program Example

  2. The SIO_GET_ATM_ADDRESS Program Example

 

Setting the IOCTL SIO_ENABLE_CIRCULAR_QUEUEING Program Example

 

Create a new empty Win32 console mode application and add the project/solution name.

 

Winsock 2 socket options and ioctls: Setting the IOCTL SIO_ENABLE_CIRCULAR_QUEUEING program example

 

Add the following source code.

 

// Description:

//    This sample shows how to set the ioctl SIO_ENABLE_CIRCULAR_QUEUEING.

//    This ioctl is very difficult to prove that it works. You need to

//    start blasting datagram packets as quickly as possible and capture

//    the results with Microsoft Network Monitor to find out which packets

//    got dropped.

//

// No command Line arguments

//    Sio_enable_circular_queueing

//

// Link to ws2_32.lib

#include <winsock2.h>

#include <ws2tcpip.h>

#include <stdio.h>

 

// Function: main

// Description:

//    Load Winsock, create a socket, and set the ioctl. Afterwards

//    call the ioctl again to retrieve its value.

int main(int argc, char **argv)

{

    WSADATA     wsd;

    SOCKET        s;

    int                     ret;

    DWORD         dwBytesRet;

    BOOL              bOpt;

 

    // Load Winsock

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)

    {

        printf("WSAStartup() failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf("WSAStartup() is OK!\n");

 

    // Creat a socket

    s = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);

    if (s == INVALID_SOCKET)

    {

        printf("WSASocket() failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf("WSASocket() is OK!\n");

    // Set the ioctl

    printf("Setting the ioctl...\n");

    bOpt = TRUE;

    ret = WSAIoctl(s, SIO_ENABLE_CIRCULAR_QUEUEING, &bOpt, sizeof(bOpt), NULL, 0, &dwBytesRet, NULL, NULL);

    if (ret == SOCKET_ERROR)

    {

        printf(" WSAIoctl(SIO_ENABLE_CIRCULAR_QUEUEING) failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf(" WSAIoctl(SIO_ENABLE_CIRCULAR_QUEUEING) is OK!\n");

    // Get the ioctl

    printf("Getting the ioctl...\n");

    ret = WSAIoctl(s, SIO_ENABLE_CIRCULAR_QUEUEING, NULL, 0, &bOpt, sizeof(bOpt), &dwBytesRet, NULL, NULL);

    if (ret == SOCKET_ERROR)

    {

        printf(" WSAIoctl(SIO_ENABLE_CIRCULAR_QUEUEING) failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf(" WSAIoctl(SIO_ENABLE_CIRCULAR_QUEUEING) is OK!\n");

    if (bOpt == TRUE)

        printf("Circular queuing is TRUE!\n");

    else

        printf("Circular queuing is FALSE!\n");

    // Cleanup

    if(closesocket(s) == 0)

        printf("closesocket() should be fine!\n");

    else

        printf("closesocket() failed with error code %d\n", WSAGetLastError());

    if(WSACleanup() == 0)

        printf("WSACleanup() is OK!\n");

    else

        printf("WSACleanup() failed with error code %d\n", WSAGetLastError());

    return 0;

}

 

Build and run the project.

 

Winsock 2 socket options and ioctls: Setting the IOCTL SIO_ENABLE_CIRCULAR_QUEUEING program example - a sample output

 

The SIO_GET_ATM_ADDRESS Program Example

 

Create a new empty Win32 console mode application and add the project/solution name.

 

Winsock 2 socket options and ioctls: The SIO_GET_ATM_ADDRESS program example

 

Add the following source code.

 

#include "support.h"

#include <stdio.h>

 

int main(int argc, char **argv)

{

    WSADATA      wsd;

    SOCKET       s;

    DWORD        deviceID, bytes, dwAddrLen = 256;

    ATM_ADDRESS  addr;

    SOCKADDR_ATM atm_addr;

    char         szAddress[256];

    WSAPROTOCOL_INFO pProtocolInfo;

 

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)

    {

        printf("WSAStartup() failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf("WSAStartup() is OK!\n");

 

    if (FindProtocol(&pProtocolInfo) == FALSE)

    {

        printf("FindProtocol() returned NULL for ATM. Check the ATM adapter/NIC!!\n");

        WSACleanup();

        return -1;

    }

    else

        printf("FindProtocol() returned something for ATM!\n");

 

    s = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,&pProtocolInfo, 0, WSA_FLAG_OVERLAPPED);

    if (s == INVALID_SOCKET)

    {

        printf("WSASocket() failed with error code %d\n", WSAGetLastError());

        WSACleanup();

        return -1;

    }

    else

       printf("WSASocket() is OK!\n");

 

    deviceID = 0;

    if (WSAIoctl(s, SIO_GET_ATM_ADDRESS, (LPVOID) &deviceID,

        sizeof(DWORD), (LPVOID) &addr, sizeof(ATM_ADDRESS),

        &bytes, NULL, NULL) == SOCKET_ERROR)

    {

        printf("WSAIoctl() error %d\n", WSAGetLastError());

        WSACleanup();

        return -1;

    }

    else

        printf("WSAIoctl() is OK!\n");

 

    ZeroMemory((PVOID)&atm_addr, sizeof(atm_addr));

    atm_addr.satm_family                 = AF_ATM;

    atm_addr.satm_number.AddressType     = ATM_NSAP;

    atm_addr.satm_number.NumofDigits     = ATM_ADDR_SIZE;

    atm_addr.satm_blli.Layer2Protocol    = SAP_FIELD_ANY;

    atm_addr.satm_blli.Layer3Protocol    = SAP_FIELD_ABSENT;

    atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT;

 

    memcpy(atm_addr.satm_number.Addr, &addr.Addr, ATM_ADDR_SIZE);

    ZeroMemory((PVOID)szAddress, sizeof(szAddress));

 

    if (WSAAddressToString((LPSOCKADDR)&atm_addr, sizeof(atm_addr), &pProtocolInfo, (LPWSTR)szAddress, &dwAddrLen))

    {

        printf("WSAAddressToString() error %d\n", WSAGetLastError());

        return(FALSE);

    }

    else

         printf("WSAAddressToString() is fine!\n");

     printf("The atm address (if any): <%S>\n", szAddress);

 

    // Cleanup

    if(closesocket(s) == 0)

           printf("closesocket() should be fine!\n");

    else

           printf("closesocket() failed with error code %d\n", WSAGetLastError());

     if(WSACleanup() == 0)

           printf("WSACleanup() is OK!\n");

     else

           printf("WSACleanup() failed with error code %d\n", WSAGetLastError());

    return 0;

}

 

Add new header file, support.h.

 

Winsock 2 socket options and ioctls: The SIO_GET_ATM_ADDRESS program example - adding the support.h header file

 

Add the source code.

 

// Link to ws2_32.lib

#include <winsock2.h>

#include <ws2atm.h>

 

// Prototypes

int  GetNumATMInterfaces(SOCKET s);

BOOL GetATMAddress(SOCKET s, int device, ATM_ADDRESS *atmaddr);

BOOL FindProtocol(WSAPROTOCOL_INFO *lpProto);

void AtoH( CHAR *szDest, CHAR *szSource, INT iCount );

 

Add the header file definition, support.cpp.

 

--------------------------------------------------------------------

Winsock 2 socket options and ioctls: The SIO_GET_ATM_ADDRESS program example - adding the support.cpp, the definition file

 

Add the source code.

 

#include "support.h"

#include <stdio.h>

 

UCHAR BtoH( CHAR ch );

 

int  GetNumATMInterfaces(SOCKET s)

{

    DWORD  dwNum, nbytes = sizeof(DWORD);

 

    if (WSAIoctl(s, SIO_GET_NUMBER_OF_ATM_DEVICES, NULL, 0,

        (LPVOID)&dwNum, sizeof(DWORD), &nbytes, NULL, NULL) == SOCKET_ERROR)

    {

        return -1;

    }

    return dwNum;

}

 

BOOL GetATMAddress(SOCKET s, int device, ATM_ADDRESS *atmaddr)

{

    DWORD bytes;

 

    if (WSAIoctl(s, SIO_GET_ATM_ADDRESS, (LPVOID)&device, sizeof(DWORD),

        (LPVOID)atmaddr, sizeof(ATM_ADDRESS), &bytes, NULL, NULL) == SOCKET_ERROR)

    {

        return FALSE;

    }

    return TRUE;

}

 

BOOL FindProtocol(WSAPROTOCOL_INFO *lpProto)

{

    WSAPROTOCOL_INFO *lpProtocolBuf=NULL;

    DWORD             dwErr, dwRet, dwBufLen=0, i;

 

    if (WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen) != SOCKET_ERROR)

    {

        // This should never happen as there is a NULL buffer

        printf("WSAEnumProtocols() failed!\n");

        return FALSE;

     }

    else if ((dwErr = WSAGetLastError()) != WSAENOBUFS)

    {

         // We failed for some reason not relating to buffer size - also odd

         printf("WSAEnumProtocols() failed with error code %d\n", dwErr);

         return FALSE;

    }

    else

         printf("WSAEnumProtocols() should be fine!\n");

 

    // Allocate the correct buffer size for WSAEnumProtocols as well as the buffer to return

    lpProtocolBuf = (WSAPROTOCOL_INFO *)GlobalAlloc(GMEM_FIXED, dwBufLen);

 

    if (lpProtocolBuf == NULL)

    {

          printf("GlobalAlloc() for protocol buffer failed with error code %d\n", GetLastError());

          return FALSE;

    }

    else

          printf("GlobalAlloc() is OK for protocol buffer...\n");

 

    dwRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);

    if (dwRet == SOCKET_ERROR)

    {

          printf("WSAEnumProtocols() failed wit herror code %d\n", WSAGetLastError());

          GlobalFree(lpProtocolBuf);

          return FALSE;

    }

    else

         printf("WSAEnumProtocols() is OK!\n");

 

    // Loop through the returned protocol information looking for those that are in the AF_ATM address family.

    for (i=0; i < dwRet ;i++)

    {

          printf("Protocol: %S\n", lpProtocolBuf[i].szProtocol);

          if ( (lpProtocolBuf[i].iAddressFamily == AF_ATM) && (lpProtocolBuf[i].iSocketType == SOCK_RAW) &&

             (lpProtocolBuf[i].iProtocol == ATMPROTO_AAL5) )

        {

            memcpy(lpProto, &lpProtocolBuf[i], sizeof(WSAPROTOCOL_INFO));

            GlobalFree(lpProtocolBuf);

            return TRUE;

        }

    }

    GlobalFree(lpProtocolBuf);

    return FALSE;

}

 

// AtoH () coverts the ATM address specified in the string (ascii) format to the binary(hexadecimal) format.

void AtoH( CHAR *szDest, CHAR *szSource, INT iCount )

{

    while (iCount--)

    {

        *szDest++ = ( BtoH ( *szSource++ ) << 4 ) + BtoH ( *szSource++ );

    }

    return;

}

 

// BtoH () returns the equivalent binary value for an individual character specified in the ascii format.

UCHAR BtoH( CHAR ch )

{

    if ( ch >= '0' && ch <= '9' )

    {

        return ( ch - '0' );

    }

 

    if ( ch >= 'A' && ch <= 'F' )

    {

        return ( ch - 'A' + 0xA );

    }

 

    if (ch >= 'a' && ch <= 'f' )

    {

        return ( ch - 'a' + 0xA );

    }

    // Illegal values in the address will not be excepted

    return -1;

}

 

Build and run the project.

 

Winsock 2 socket options and ioctls: The SIO_GET_ATM_ADDRESS program example - a sample output

 

 

 


< IP_TOS & SIO_ADDRESS_LIST_QUERY Examples | Socket Options & IOCTLs Main | SIO_GET_BROADCAST_ADDRESS & SO_KEEPALIVE_VALS Examples >