< FIONBIO, FIONREAD & SIO | Socket Options & IOCTLs Main | IP_TOS & SIO_ADDRESS_LIST_QUERY Examples >


 

 

Socket Options and Ioctls 7 part 4

 

 

What do we have in this chapter 7 part 4?

  1. Secure Socket Layer (SSL) Ioctl Commands

  2. SO_SSL_GET_CAPABILITIES

  3. SO_SSL_GET_FLAGS

  4. SO_SSL_SET_FLAGS

  5. SO_SSL_GET_PROTOCOLS

  6. SO_SSL_SET_PROTOCOLS

  7. SO_SSL_SET_VALIDATE_CERT_HOOK

  8. SO_SSL_PERFORM_HANDSHAKE

  9. ATM Ioctl Commands

  10. SIO_GET_NUMBER_OF_ATM_DEVICES

  11. SIO_GET_ATM_ADDRESS

  12. SIO_ASSOCIATE_PVC

  13. SIO_GET_ATM_CONNECTION_ID

  14. Program Examples

  15. The Multicast and IP_TTL Option Program Example

 

Secure Socket Layer Ioctl Commands

 

SO_SSL_GET_CAPABILITIES

 

Which Function?

Input

Output

Description

WSAIoctl()

None

DWORD

Returns the Winsock security provider's capabilities

 

This command retrieves a set of flags describing the Windows Sockets security provider's capabilities. The output buffer must be a pointer to a DWORD bit field. At present, only the flag SO_CAP_CLIENT is defined.

 

SO_SSL_GET_FLAGS

 

Which Function?

Input

Output

Description

WSAIoctl()

None

DWORD

Returns s-channel–specific flags associated with socket

 

This command retrieves s-channel-specific flags associated with a particular socket. The output buffer must be a pointer to a DWORD bit field. See SO_SSL_SET_FLAGS below for details of valid flags.

 

SO_SSL_SET_FLAGS

 

Which Function?

Input

Output

Description

WSAIoctl()

DWORD

None

Sets the socket's s-channel–specific flags

 

The input buffer here must be a pointer to a DWORD bit field. Currently, the only flag defined is SSL_FLAG_DEFER_HANDSHAKE, which allows the application to send and receive plain text data before switching to cipher text. This flag is required for setting up communication through proxy servers.

Normally, the Windows Sockets security provider performs the secure handshake in the Windows Sockets connect function. However, if this flag is set, the handshake is deferred until the application issues the SO_SSL_PERFORM_HANDSHAKE control code. After the handshake, this flag is reset.

 

SO_SSL_GET_PROTOCOLS

 

Which Function?

Input

Output

Description

WSAIoctl()

None

SSLPROTOCOLS

Returns a list of protocols that the security provider supports

 

This command retrieves a list of protocols that the provider currently supports on this socket. The output buffer must be a pointer to a SSLPROTOCOLS structure, as described here:

 

typedef struct _SSLPROTOCOL

{

    DWORD dwProtocol;

    DWORD dwVersion;

    DWORD dwFlags;

} SSLPROTOCOL, *LPSSLPROTOCOL;

 

typedef struct _SSLPROTOCOLS

{

    DWORD       dwCount;

    SSLPROTOCOL ProtocolList[1];

} SSLPROTOCOLS, FAR *LPSSLPROTOCOLS;

 

Valid protocols for the dwProtocol field include SSL_PROTOCOL_SSL2, SSL_PROTOCOL_SSL3, and SSL_PROTOCOL_PCT1.

 

SO_SSL_SET_PROTOCOLS

 

Which Function?

Input

Output

Description

WSAIoctl()

SSLPROTOCOLS

None

Sets a list of protocols that the underlying provider should support

 

This ioctl command specifies a list of protocols that the provider is to support on this socket. The input buffer must be a pointer to the SSLPROTOCOLS structure described previously.

 

SO_SSL_SET_VALIDATE_CERT_HOOK

 

Which Function?

Input

Output

Description

WSAIoctl()

SSLVALIDATECERTHOOK

None

Sets the validation function for accepting SSL certificates

 

This ioctl command sets the pointer to the socket's certificate validation hook. It is used to specify the callback function the Windows Sockets security provider invokes when it receives a set of credentials from the remote party. The input buffer must be a pointer to the SSLVALIDATECERTHOOK structure, described as follows:

 

typedef struct

{

    SSLVALIDATECERTFUNC    HookFunc;

    LPVOID                 pvArg;

} SSLVALIDATECERTHOOK, *PSSLVALIDATECERTHOOK;

 

The HookFunc field is a pointer to a certificate validation callback function; pvArg is a pointer to application-specific data and can be used by the application for any purpose.

 

SO_SSL_PERFORM_HANDSHAKE

 

Which Function?

Input

Output

Description

WSAIoctl()

None

None

Initiates a secure handshake on a connected socket

 

This ioctl command initiates the secure handshake sequence on a connected socket in which the SSL_FLAG_DEFER_HANDSHAKE flag has been set prior to the connection. Data buffers are not required, but the SSL_FLAG_DEFER_HANDSHAKE flag will be reset.

 

ATM Ioctl Commands

 

The ioctl commands in this section are specific to the ATM protocol family. They are fairly basic, dealing mainly with obtaining the number of ATM devices and ATM addresses of the local interfaces.

 

SIO_GET_NUMBER_OF_ATM_DEVICES

 

Which Function?

Input

Output

Winsock Version

Description

WSAIoctl()

None

DWORD

2+

Returns the number of ATM adapters

 

This ioctl command fills the output buffer pointed to by lpvOutBuffer with a DWORD containing the number of ATM devices in the system. Each specific device is identified by a unique ID, in the range 0 to the number returned by this ioctl command minus 1.

 

SIO_GET_ATM_ADDRESS

 

Which Function?

Input

Output

Winsock Version

Description

WSAIoctl()

DWORD

ATM_ADDRESS

2+

Returns the ATM address for the given device

 

This ioctl command retrieves the local ATM address associated with the specified device. A device ID of type DWORD is specified in the input buffer for this ioctl command, and the output buffer pointed to by lpvOutBuffer will be filled with an ATM_ADDRESS structure containing a local ATM address suitable for use with bind().

 

SIO_ASSOCIATE_PVC

 

Which Function?

Input

Output

Winsock Version

Description

WSAIoctl()

ATM_PVC_PARAMS

None

2+

Associates socket with a permanent virtual circuit

 

This ioctl command associates the socket with a permanent virtual circuit (PVC), as indicated in the input buffer, which contains the ATM_PVC_PARAMS structure. The socket should be of the AF_ATM address family. After successfully returning from this function, the application is able to start sending and receiving data as if the connection has been set up. The ATM_PVC_PARAMS structure is defined as:

 

typedef struct

{

    ATM_CONNECTION_ID   PvcConnectionId;

    QOS                 PvcQos;

} ATM_PVC_PARAMS;

 

typedef struct

{

    DWORD  DeviceNumber;

    DWORD  VPI;

    DWORD  VCI;

} ATM_CONNECTION_ID;

 

SIO_GET_ATM_CONNECTION_ID

 

Which Function?

Input

Output

Winsock Version

Description

Both

None

ATM_CONNECTION_ID

2+

Determines whether OOB data has been read

 

This ioctl command retrieves the ATM Connection ID associated with the socket. Upon successfully returning from this function, the output buffer pointed to by lpvOutBuffer is filled with an ATM_CONNECTION_ID structure containing the device number and Virtual Path/Channel Identifier (VPI/VCI) values, which are defined in the earlier entry for SIO_ASSOCIATE_PVC.

 

Program Examples

 

The Multicast and IP_TTL Option Program Example

 

The following program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field.

 

Winsock 2 socket options and ioctls: program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field

 

Add the following source code.

 

// Description:

//    This is a simple multicast application which illustrates

//    the use of the IP_TTL option to modify the time-to-live

//    field of the IP header similar to the SIO_MULTIPOINT_SCOPE

//    ioctl does except this applies to any kind of IP traffic.

//

// Command line arguments:

//    ip_multicast_ttl [s|r] ttl

//      s        Sender

//      r        Receiver

//      ttl      Integer TTL value

//

// Vista issue: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=329162

//

// A program that includes Winsock.h should only link with Wsock32.lib

//

// Link to ws2_32.lib

#include <winsock2.h>

// Windows Server 2003 and Windows XP

#include <Ws2tcpip.h>

#include <stdio.h>

 

#define MAX_BUF             64

 

// Change the IP accordingly for testing

// Multicast address range 224.0.0.0 - 239.255.255.255

// http://www.iana.org/assignments/multicast-addresses/

#define MULTICAST_IP       "192.168.1.1"

#define MULTICAST_PORT      24000

 

// Function: usage

// Description: Prints usage information

int usage(char *progname)

{

    printf("Usage: %s s|r ttl\n", progname);

    printf("          s = sender\n");

    printf("          r = receiver\n");

    printf("        ttl = multicast TTL value\n");

    printf("Example: %s s 100\n", progname);

    printf("Example: %s r 100\n", progname);

    return 0;

}

 

// Function: main

// Description:

//    Load Winsock, parse the arguments and start either the

//    multicast sender or receiver. Before sending data set the IP_TTL to the specified value.

int main(int argc, char **argv)

{

    WSADATA        wsd;

    SOCKET         s;

    // struct ipv6_mreq for IPv6

    struct ip_mreq mcast; // IPv4

    // or better one, use struct ip_mreq_source/IP_MREQ_SOURCE/*PIP_MREQ_SOURCE

    // http://msdn.microsoft.com/en-us/library/ms738704(VS.85).aspx

    // Vista or later use GROUP_REQ and the GROUP_SOURCE_REQ structures which for both IPv6 and IPv4

    SOCKADDR_IN    local, from;

    int            ttl, ttlsz, fromsz, ret;

    char        databuf[MAX_BUF];

    BOOL     bReceive=FALSE;

 

    // Parse the command line

    if (argc < 2)

    {

         usage(argv[0]);

         exit(1);

     }

 

    if (tolower(argv[1][0]) == 's')

        bReceive = FALSE;

    else if (tolower(argv[1][0]) == 'r')

        bReceive = TRUE;

    else

        usage(argv[0]);

 

    ttl = atoi(argv[2]);

 

    // Load winsock

    if (WSAStartup(MAKEWORD(2,2), &wsd))

    {

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

        return -1;

    }

    else

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

 

    s = socket(AF_INET, SOCK_DGRAM, 0);

    if (s == INVALID_SOCKET)

    {

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

        return -1;

    }

    else

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

 

    if (bReceive)

    {

        local.sin_family = AF_INET;

        local.sin_port = htons(MULTICAST_PORT);

        local.sin_addr.s_addr = INADDR_ANY;

 

        if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)

        {

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

            return -1;

        }

        else

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

    }

 

            // Join the multicast group

            // For XP sp2 and Windows 2003 not needed in order to send,

            // only the receivers need to join a multicast group in order to receive

            if(bReceive)

            {

                        mcast.imr_multiaddr.s_addr = inet_addr(MULTICAST_IP);

                        mcast.imr_interface.s_addr = INADDR_ANY;

                       

                        if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mcast, sizeof(mcast)) == SOCKET_ERROR)

                        {

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

                                    return -1;

                        }

                        else

                                    printf("setsockopt(IP_ADD_MEMBERSHIP) is OK!\n");

            }

 

    // Set the TTL to our value

    ttlsz = sizeof(ttl);

    if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) == SOCKET_ERROR)

    {

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

        return -1;

    }

    else

        printf("setsockopt(IP_MULTICAST_TTL) is OK!\n");

 

    // Verify

    if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, &ttlsz) == SOCKET_ERROR)

    {

        printf("getsockopt(IP_MULTICAST_TTL) failed: %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf("getsockopt(IP_MULTICAST_TTL) is OK!\n");

 

    printf("Multicast TTL is set to: %d\n", ttl);

 

    if (bReceive)

    {

        // Receive some data

        fromsz = sizeof(from);

        ret = recvfrom(s, databuf, MAX_BUF, 0, (SOCKADDR *)&from, &fromsz);

        if (ret == SOCKET_ERROR)

        {

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

            return -1;

        }

        else

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

 

        databuf[ret] = 0;

        printf("read: [%s] from [%s]\n", databuf, inet_ntoa(from.sin_addr));

    }

    else

    {

        // Send some data

        SOCKADDR_IN to;

 

        memset(databuf, '$', MAX_BUF);

 

        to.sin_family = AF_INET;

        to.sin_port = htons(MULTICAST_PORT);

        to.sin_addr.s_addr = inet_addr(MULTICAST_IP);

 

        ret = sendto(s, databuf, MAX_BUF-1, 0, (SOCKADDR *)&to, sizeof(to));

 

        if (ret == SOCKET_ERROR)

        {

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

            return -1;

        }

        else

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

        printf("Sent %d bytes to %s\n", ret, inet_ntoa(to.sin_addr));

    }

 

    // 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: program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field, sample output without argument

 

Run the project as receiver.

 

Winsock 2 socket options and ioctls: program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field - sample output acting as receiver

 

Run the project as sender.

 

Winsock 2 socket options and ioctls: program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field - sample output acting as sender

 

The previous receiver screenshot sample when the communication was completed.

 

Winsock 2 socket options and ioctls: program example demonstrates the multicast application which uses the IP_TTL option to modify the time-to-live (TTL) field - sample receiver when the communication was completed

 

 

 


< FIONBIO, FIONREAD & SIO | Socket Options & IOCTLs Main | IP_TOS & SIO_ADDRESS_LIST_QUERY Examples >