< SOL/SO & IRLMP | Socket Options & IOCTLs Main | FIONBIO, FIONREAD & SIO >


 

 

Socket Options and Ioctls 7 part 2

 

 

What do we have in this chapter 7 part 2?

  1. IP_OPTIONS

  2. IP_HDRINCL

  3. IP_TOS

  4. IP_TTL

  5. IP_MULTICAST_IF

  6. IP_MULTICAST_TTL

  7. IP_MULTICAST_LOOP

  8. IP_ADD_MEMBERSHIP

  9. IP_DROP_MEMBERSHIP

  10. IP_ADD_SOURCE_MEMBERSHIP

  11. IP_DROP_SOURCE_MEMBERSHIP

  12. IP_BLOCK_SOURCE

  13. IP_UNBLOCK_SOURCE

  14. IP_DONTFRAGMENT

  15. IP_PKTINFO

  16. IPPROTO_IPV6 Option Level

  17. IPV6_HDRINCL

  18. IPV6_UNICAST_HOPS

  19. IPV6_MULTICAST_IF

  20. IPV6_MULTICAST_HOPS

  21. IPV6_MULTICAST_LOOP

  22. IPV6_ADD_MEMBERSHIP, IPV6_JOIN_GROUP

  23. IPV6_DROP_MEMBERSHIP, IPV6_LEAVE_GROUP

  24. IPV6_PKTINFO

  25. IPPROTO_RM Option Level

  26. RM_RATE_WINDOW_SIZE

  27. RM_SET_MESSAGE_BOUNDARY

  28. RM_FLUSHCACHE

  29. RM_SENDER_WINDOW_ADVANCE_METHOD

  30. RM_SENDER_STATISTICS

  31. RM_LATEJOIN

  32. RM_SET_SEND_IF

  33. RM_ADD_RECEIVE_IF

  34. RM_DEL_RECEIVE_IF

  35. RM_SEND_WINDOW_ADV_RATE

  36. RM_USE_FEC

  37. RM_SET_MCAST_TTL

  38. RM_RECEIVER_STATISTICS

  39. IPPROTO_TCP Option Level

  40. TCP_NODELAY

  41. NSPROTO_IPX Option Level

  42. IPX_PTYPE

  43. IPX_FILTERPTYPE

  44. IPX_STOPFILTERPTYPE

  45. IPX_DSTYPE

  46. IPX_EXTENDED_ADDRESS

  47. IPX_RECVHDR

  48. IPX_MAXSIZE

  49. IPX_ADDRESS

  50. IPX_GETNETINFO

  51. IPX_GETNETINFO_NORIP

  52. IPX_SPXGETCONNECTIONSTATUS

  53. IPX_ADDRESS_NOTIFY

  54. IPX_MAX_ADAPTER_NUM

  55. IPX_RERIPNETNUMBER

  56. IPX_RECEIVE_BROADCAST

  57. IPX_IMMEDIATESPXACK

  58. Ioctlsocket(), WSAIoctl(), and WSANSPIoctl()

 

 

IP_OPTIONS

 

optval Type

Get/Set

Winsock Version

Description

char [ ]

Both

1+

Gets or sets IP options within the IP header

 

This flag allows you to set various IP options within the IP header. Some of the possible options are:

  1. Security and handling restrictions. RFC 1108.

  2. Record route. Each router adds its IPv4 address to the header.

  3. Timestamp. Each router adds its IPv4 address and time.

  4. Loose source routing. The packet is required to visit each IPv4 address listed in the option header.

  5. Strict source routing. The packet is required to visit only those IPv4 addresses listed in the option header.

 

Be aware that hosts and routers do not support all of these options. When setting an IPv4 option, the data that you pass into the setsockopt call follows the structure shown in Figure 7-2. The IPv4 option header can be up to 40 bytes long.

 

 

Figure 7-2 IP option header format

 

The code field indicates which type of IP option is present. For example, the value 0x7 represents the record route option. Length is simply the length of the option header, and offset is the offset value into the header where the data portion of the header begins. The data portion of the header is specific to the particular option. In the following code snippet, we set up the record route option. Notice that we declare a structure (struct ip_option_hdr) that contains the first three option values (code, length, offset), and then we declare the option-specific data as an array of nine unsigned long integers because the data to be recorded is up to nine IPv4 addresses. Remember that the maximum size of the IPv4 option header is 40 bytes; however, our structure occupies only 39 bytes. The system will pad the header to a multiple of a 32-bit word for you (up to 40 bytes).

 

struct ip_option_hdr

{

    unsigned char    code;

    unsigned char    length;

    unsigned char    offset;

    unsigned long    addrs[9];

} opthdr;

 

...

 

ZeroMemory((char *)&opthdr, sizeof(opthdr));

opthdr.code = 0x7;

opthdr.length = 39;

opthdr.offset = 4;  // Offset to first address (addrs)

ret = setsockopt(s, IPPROTO_IP, IP_OPTIONS, (char *)&opthdr, sizeof(opthdr));

 

Once the option is set, it applies to any packets sent on the given socket. At any pointer thereafter, you can call getsockopt() with IP_OPTIONS to retrieve which options were set; however, this will not return any data filled into the option-specific buffers. To retrieve the data set in the IPv4 options, either the socket must be created as a raw socket (SOCK_RAW) or the IP_HDRINCL option should be set, in which case, the IPv4 header is returned along with data after a call to a Winsock receive() function.

 

IP_HDRINCL

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

2+

If TRUE, IP header is submitted with data to Winsock send() calls.

 

Setting the IP_HDRINCL option to TRUE causes the send function to include the IPv4 header ahead of the data Thus, when you call a Winsock send function, you must include the entire IPv4 header ahead of the data and fill each field of the IP header correctly. Note that the IPv4 network stack will fragment the data portion of the packet if necessary when this option is set. This option is valid only for sockets of type SOCK_RAW. Figure 7-3 shows what the IPv4 header should look like. This option is available only in Windows 2000 and later versions.

 

Figure 7-3 The IPv4 header

 

The first field of the header is the IPv4 version, which is 4. The header length is the number of 32-bit words in the header. An IP header must always be a multiple of 32 bits. The next field is the type of service field. Consult the IP_TOS socket option, discussed in the next section, for more information. The total length field is the length in bytes of the IP header and data. The identification field is a unique value used to identify each IPv4 packet sent. Normally, the system increments this value with each packet sent. The flags and fragmentation offset fields are used when IPv4 packets are fragmented into smaller packets. The TTL limits the number of routers through which the packet can pass. Each time a router forwards the packet, the TTL is decremented by 1. Once the TTL is 0, the packet is dropped. This limits the amount of time a packet can be live on the network. The protocol field is used to demultiplex incoming packets. Some of the valid protocols that use IP addressing are TCP, UDP, IGMP, and ICMP. The checksum is the 16-bit one's complement sum of the header. It is calculated over the header only and not the data. The next two fields are the 32-bit IP source and destination addresses. The IPv4 options field is a variable length field that contains optional information, usually regarding security or routing.

The easiest way to include an IPv4 header with the data you are sending is to define a structure that contains the IP header and the data and pass it into the Winsock send() call. This option works only in Windows 2000 and later versions.

 

IP_TOS

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

IPv4 type of service

 

The type of service (TOS) is a field present in the IPv4 header that is used to signify certain characteristics of a packet. The field is eight bits long and is broken into three parts: a 3-bit precedence field (which is ignored), a 4-bit TOS field, and the remaining bit (which must be 0). The four TOS bits are minimize delay, maximize throughput, maximize reliability, and minimize monetary costs. Only one bit can be set at a time. All four bits being 0 implies normal service. RFC 1340 specifies the recommended bits to set for various standard applications such as TCP, SMTP, and NNTP. In addition, RFC 1349 contains some corrections to the original RFC.

Interactive applications, such as Rlogin or Telnet, might want to minimize delay. Any kind of file transfer, such as FTP, is interested in maximum throughput. Maximum reliability is used by network management (Simple Network Management Protocol, or SNMP) and routing protocols. Finally, Usenet news (Network News Transfer Protocol, or NNTP) is an example of minimizing monetary costs. The IP_TOS option is not available in Windows CE.

There is another issue when you attempt to set the TOS bits on a QOS-enabled socket. Because IP precedence is used by QOS to differentiate levels of service, it is undesirable to allow developers the capability to change these values. As a result, when you call setsockopt with IP_TOS on a QOS-enabled socket, the QOS service provider intercepts the call to verify whether the change can take place.

 

IP_TTL

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

IP TTL parameter

 

The TTL field is present in an IP header. Datagrams use the TTL field to limit the number of routers through which the datagram can pass. The purpose of this limitation is to prevent routing loops in which datagrams can spin in circles forever. The idea behind this is that each router that the datagram passes through decrements the datagram's TTL value by 1. When the value equals 0, the datagram is discarded. This option is not available in Windows CE.

 

IP_MULTICAST_IF

 

optval Type

Get/Set

Winsock Version

Description

unsigned long

Both

1+

Gets or sets the local interface for outgoing multicast data

 

The IP multicast interface (IF) option sets which local interface multicast data will be sent from. This option is only of interest on machines that have more than one connected network interface (such as network card or modem). The optval parameter should be an unsigned long integer representing the binary IP address of the local interface. The function inet_addr can be used to convert a string IP dotted decimal address to an unsigned long integer, as in the following sample:

 

DWORD    mcastIF;

 

// First join socket s to a multicast group

mcastIF = inet_addr("129.113.43.120");

ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mcastIF, sizeof(mcastIF));

 

IP_MULTICAST_TTL

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

Gets or sets the TTL on multicast packets for this socket

 

Similar to the IP TTL, this option performs the same function except that it applies only to multicast data sent using the given socket. Again, the purpose of the TTL is to prevent routing loops, but in the case of multicasting, setting the TTL narrows the scope of how far the data will travel. Therefore, multicast group members must be within “range” to receive datagrams. The default TTL value for multicast datagrams is 1.

 

IP_MULTICAST_LOOP

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, data sent to a multicast address will be echoed to the socket's incoming buffer.

 

By default, when you send IP multicast data, the data will be looped back to the sending socket if it is also a member of that multicast group. If you set this option to FALSE, any data sent will not be posted to the incoming data queue for the socket.

 

IP_ADD_MEMBERSHIP

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq

Set only

1+

Adds the socket to the given IP group membership

 

This option is the Winsock 1 method of adding a socket to an IP multicast group. This is done by creating a socket of address family AF_INET and the socket type SOCK_DGRAM with the socket function. To add the socket to a multicast group, use the following structure.

 

struct ip_mreq

{

    struct in_addr  imr_multiaddr;

    struct in_addr  imr_interface;

};

 

In the ip_mreq structure, imr_multiaddr is the binary address of the multicast group to join, while imr_interface is the local interface on which the group is joined. The imr_interface field is either the binary IPv4 address of a local interface or the value INADDR_ANY, which can be used to select the default interface (according to the routing table).

 

IP_DROP_MEMBERSHIP

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq

Set only

1+

Removes the socket from the given IP group membership

 

This option is the opposite of IP_ADD_MEMBERSHIP. By calling this option with an ip_mreq structure that contains the same values used when joining the given multicast group, the socket s will be removed from the given group.

 

IP_ADD_SOURCE_MEMBERSHIP

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq_source

Set only

2+

Joins a multicast group but accepts data from only the given source

 

This multicast option joins the specified multicast group on the given interface but will accept data from only the given source IPv4 address (this is know as an include list). This option may be called multiple times to build an include list of multiple acceptable sources. The input structure is defined as:

 

struct ip_mreq_source {

      struct in_addr  imr_multiaddr;

      struct in_addr  imr_sourceaddr;

      struct in_addr  imr_interface

};

 

The first field is the 32-bit multicast address, the second field is the 32-bit IPv4 address of the acceptable source, and the last field is the 32-bit IPv4 address of the local interface on which to join the group. This option is supported on Windows XP and later versions and requires the local network to be IGMPv3 enabled.

 

IP_DROP_SOURCE_MEMBERSHIP

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq_source

Set only

2+

Remove the given IPv4 source from the list of acceptable sources.

 

This option is the complement to IP_ADD_SOURCE_MEMBERSHIP. Once one or more sources for a particular multicast group are added via IP_ADD_SOURCE_MEMBERSHIP, this option can be used to remove selected sources from the include list. Using these two options, an application can manage the list of sources to accept multicast data from a given multicast address. This option requires Windows XP and an IGMPv3-enabled network.

 

IP_BLOCK_SOURCE

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq_source

Set only

2+

Joins a multicast group but accepts data from everyone except the given IPv4 source.

 

This and the IP_UNBLOCK_SOURCE options are used to build an exclude list of sources for multicast traffic. The IP_BLOCK_SOURCE specifies a source from which multicast data will not be accepted. This option may be called multiple times to exclude additional sources. This option requires Windows XP and an IGMPv3-enabled network.

 

IP_UNBLOCK_SOURCE

 

optval Type

Get/Set

Winsock Version

Description

struct ip_mreq_source

Both

2+

Adds the given IPv4 source to the list of acceptable sources.

 

This option removes the given source from the exclude list so that multicast data received from the removed source will be propagated to the socket. This option requires Windows XP and an IGMPv3-enabled network.

 

IP_DONTFRAGMENT

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, do not fragment IP datagrams.

 

This flag tells the network not to fragment the IPv4 datagram during transmission. However, if the size of the IPv4 datagram exceeds the maximum transmission unit (MTU) and the IP don't fragment flag is set within the IPv4 header, the datagram will be dropped and an ICMP error message (“fragmentation needed but don't fragment bit set”) will be returned to the sender. This option is not available on Windows CE.

 

IP_PKTINFO

 

optval Type

Get/Set

Winsock Version

Description

int

Set only

2+

Indicates whether packet information should be returned from WSARecvMsg()

 

This option indicates that IPv4 packet information should be returned as a part of the control buffer passed to the WSARecvMsg() API. For IPv4, the structure returned is the IN_PKTINFO defined as:

 

typedef struct in_pktinfo {

    IN_ADDR    ipi_addr;

    UINT       ipi_ifindex;

} IN_PKTINFO;

 

The first field is the 32-bit binary IPv4 address on which the packet was received. The second field is the interface index that can be correlated to a particular network adapter via the IP Helper.

 

IPPROTO_IPV6 Option Level

 

The IPPROTO_IPV6 level indicates socket options that pertain to the IPv6 protocol. Many of these options mirror the IPv4 socket options. These values are defined in WS2TCPIP.H.

 

IPV6_HDRINCL

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

2+

If TRUE, IPv6 header is submitted to Winsock send calls.

 

This option indicates that the application will supply the IPv6 header for each packet of data sent by a Winsock send call. The IPv6 stack will not perform any fragmentation for packets larger than the MTU. Applications must build the appropriate fragmentation headers for each packet sent that is larger than the MTU. This socket option is valid only for sockets of type SOCK_RAW. On IPv6, raw sockets are truly raw. Figure 7-4 shows the IPv6 header.

 

Figure 7-4 IPv6 header

 

The first field is four bits in length and is the IP version which is six. The next 8-bit field defines the traffic class. Currently, there are no well-defined values for this field. The 20-bit flow label is used to label sequences of packets that request special treatment. Again, there are no predefined values for this field. The 16-bit payload field is the length of the payload in octets. This includes any extension headers but not the basic IPv6 header itself. The 8-bit next header field indicates the protocol value of the next header. This can either be an IPv6 extension header (such as the fragmentation header) or the next encapsulated protocol (such as UDP or TCP). The 8-bit hop limit field indicates the TTL value for the packet. The last two fields are the 128-bit source and destination IPv6 addresses.

 

IPV6_UNICAST_HOPS

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

IPv6 TTL parameter

 

This option is used to set the TTL value to be used on unicast traffic sent on the socket. This is analogous to the IPv4 option IP_TTL.

 

IPV6_MULTICAST_IF

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

IPv6 multicast interface for outgoing multicast data

 

This option is analogous to the IP_MULTICAST_IF option except that it sets the outgoing interface for IPv6 multicast traffic. Also, instead of specifying the local IPv6 interface address for the outgoing traffic, the interface's scope ID is specified instead. The IP Helper function GetAdaptersAddress() can be called to obtain the local interface indices.

 

IPV6_MULTICAST_HOPS

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

IPv6 TTL parameter for multicast data

 

This option is analogous to the IP_MULTICAST_TTL option except that it sets the TTL option for IPv6 multicast traffic.

 

IPV6_MULTICAST_LOOP

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

If TRUE, data sent to a multicast address will be echoed to the socket's incoming buffer.

 

This option enables outgoing IPv6 multicast traffic to be echoed back to the sending socket if the sending socket is also a member of the multicast group. This option is analogous to the IPv4 multicast option IP_MULTICAST_LOOP.

 

IPV6_ADD_MEMBERSHIP, IPV6_JOIN_GROUP

 

optval Type

Get/Set

Winsock Version

Description

struct ipv6_mreq

Both

2+

Joins an IPv6 multicast group on the specified interface.

 

This option joins the IPv6 multicast group on a particular interface. The input parameter is defined as:

 

typedef struct           ipv6_mreq {

         struct in6_addr ipv6mr_multiaddr;

         unsigned int    ipv6mr_interface;

} IPV6_MREQ;

 

The first field is the IPv6 address of the multicast address to join, and the second field is the interface index (or scope ID) on which to join the group.

 

IPV6_DROP_MEMBERSHIP, IPV6_LEAVE_GROUP

 

optval Type

Get/Set

Winsock Version

Description

struct ipv6_mreq

Both

2+

Drops the multicast group from the given interface

 

This option drops membership of the IPv6 multicast group from the given interface. The input parameter is the struct ipv6_mreq containing the multicast group to drop from the given interface (scope ID).

 

IPV6_PKTINFO

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

Indicates whether packet information should be returned from WSARecvMsg().

 

This option indicates that IPv6 packet information should be returned as a part of the control buffer passed to the WSARecvMsg() API. For IPv6, the structure returned is the IN6_PKTINFO defined as:

 

typedef struct in6_pktinfo {

    IN6_ADDR   ipi6_addr;

    UINT       ipi6_ifindex;

} IN6_PKTINFO;

 

The first field is the binary IPv6 address on which the packet was received. The second field is the interface index that can be correlated to a particular network adapter via the IP Helper.

 

IPPROTO_RM Option Level

 

Socket options of the IPPROTO_RM level are used by the reliable multicast transport. These options are declared in wsrm.h.

 

RM_RATE_WINDOW_SIZE

 

optval Type

Get/Set

Winsock Version

Description

RM_SEND_WINDOW

Both

2+

Specifies the data rate and window size

 

This option sets the size of the send window, which determines the amount or time data remains valid for repairs. The RM_SEND_WINDOW structure is declared as:

 

typedef struct _RM_SEND_WINDOW {

      ULONG RateKbitsPerSec;

      ULONG WindowSizeInMSecs;

      ULONG WindowSizeInBytes;

} RM_SEND_WINDOW

 

The first field indicates the data rate in kilobits per second. The second field is the size of the window in milliseconds. The last field indicates the window size in bytes. The values supplied for these three fields must satisfy the equation Rate-KbitsPerSec = (WindowSizeInBytes 1024) / (WindowSizeInMSecs 1000).

 

RM_SET_MESSAGE_BOUNDARY

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

Indicates the logical size of the packet in bytes to follow

 

This option is used to send large messages in multiple chunks. For example, if a sender wishes to send a 2 MB buffer as a single packet, for performance reasons it is undesirable to submit a 2 MB buffer in a single call to send. Instead, this option is set to indicate the logical size of the forthcoming packet. Afterward, the sender may send the 2 MB packet in small chunks.

 

RM_FLUSHCACHE

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Set only

2+

Flushes the entire contents of the send window

 

This option flushes the entire contents of the send window so that no more Negative Acknowledgements (NAKs) can be satisfied. This option is currently not implemented.

 

RM_SENDER_WINDOW_ADVANCE_METHOD

 

optval Type

Get/Set

Winsock Version

Description

eWINDOW_ADVANCE_METHOD

Both

2+

Indicates how the send window advances

 

This option specifies how the send window advances. The possible values are an enumerated type:

 

enum eWINDOW_ADVANCE_METHOD

{

    E_WINDOW_ADVANCE_BY_TIME = 1,       // Default mode

    E_WINDOW_USE_AS_DATA_CACHE

};

 

The first value indicates that the window advances with time. That is, the send data is valid for the amount of time specified in WindowSizeInMSecs field of the RM_SEND_WINDOW structure. The second value indicates that data is discarded only after the send window becomes full as specified by the WindowSizeInBytes field of the RM_SEND_WINDOW structure.

 

 

RM_SENDER_STATISTICS

 

optval Type

Get/Set

Winsock Version

Description

RM_SENDER_STATS

Get only

2+

Returns statistics for a sender socket

 

This option retrieves an RM_SENDER_STATS structure that contains various network statistics for the session. This structure is defined as:

 

typedef struct _RM_SENDER_STATS

{

    ULONGLONG   DataBytesSent;          // # client data bytes sent out so far

    ULONGLONG   TotalBytesSent;         // SPM, OData and RData bytes

    ULONGLONG   NaksReceived;           // # NAKs received so far

    ULONGLONG   NaksReceivedTooLate;    // # NAKs recvd after window advanced

    ULONGLONG   NumOutstandingNaks;     // # NAKs yet to be responded to

    ULONGLONG   NumNaksAfterRData;      // # NAKs yet to be responded to

    ULONGLONG   RepairPacketsSent;      // # Repairs (RDATA) sent so far

    ULONGLONG   BufferSpaceAvailable;   // # partial messages dropped

    ULONGLONG   TrailingEdgeSeqId;      // smallest (oldest) Sequence Id in the window

    ULONGLONG   LeadingEdgeSeqId;       // largest (newest) Sequence Id in the window

    ULONGLONG   RateKBitsPerSecOverall; // internally calculated send-rate from the beginning

    ULONGLONG  RateKBitsPerSecLast;      // Send-rate calculated every

                                        // INTERNAL_RATE_CALCULATION_FREQUENCY

} RM_SENDER_STATS;

 

The comments for each field from the header file explain the structure so we won't repeat them.

 

RM_LATEJOIN

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

Allows receivers to NAK for any packet in the window

 

When this option is set, a receiver may NAK any sequence number in the advertise window upon session join.

 

RM_SET_SEND_IF

 

optval Type

Get/Set

Winsock Version

Description

ULONG

Both

2+

Sets the outgoing interface for reliable multicast traffic

 

This option sets the outgoing interface for reliable multicast traffic. The 32-bit binary address of the local outgoing interface is supplied as the input parameter.

 

RM_ADD_RECEIVE_IF

 

optval Type

Get/Set

Winsock Version

Description

ULONG

Set only

2+

Adds the given interface as a receiving interface

 

By default, when a reliable multicast receiver is created, it listens for traffic on the default interface (as indicated by the routing table). This option can be used to specify the 32-bit binary IPv4 address of the local interface to listen for traffic. This option can be specified multiple times to add more than one listening interface in the event of a multihomed machine.

 

RM_DEL_RECEIVE_IF

 

optval Type

Get/Set

Winsock Version

Description

ULONG

Set only

2+

Removes the given interface from the list of receiving interfaces

 

This option removes the supplied interface from the list of valid receiving interfaces for reliable multicast traffic. The address is supplied as a 32-bit binary IPv4 address.

 

RM_SEND_WINDOW_ADV_RATE

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

Sets the increment percentage for the send window

 

The send window advances incrementally over time so that a portion of the oldest data is discarded to make room for new data sent by the application. This option controls how much data is discarded with each incremental advance. The maximum possible increment value as a percentage of the whole window is defined as MAX_WINDOW_INCREMENT_PERCENTAGE.

 

RM_USE_FEC

 

optval Type

Get/Set

Winsock Version

Description

RM_FEC_INFO

Both

2+

Enables forward error correction on the session

 

This option enables the use of forward error correction (FEC) on the session. This RM_FEC_INFO structure is defined as:

 

typedef struct _RM_FEC_INFO

{

    USHORT              FECBlockSize;

    USHORT              FECProActivePackets;

    UCHAR               FECGroupSize;

    BOOLEAN             fFECOnDemandParityEnabled;

} RM_FEC_INFO;

 

The FECGroupSize indicates the number of original packets to build parity packets from and the FECBlockSize indicates the number of original packets plus the number of parity packets generated. FECProActivePackets indicates to transmit FEC packets always (instead of only for repair data). The fFECOnDemandParityEnabled allows receivers to request FEC repair data on demand.

 

RM_SET_MCAST_TTL

 

optval Type

Get/Set

Winsock Version

Description

int

Both

2+

Sets the TTL for reliable multicast data sent

 

This option sets the TTL value for a reliable multicast sender.

 

RM_RECEIVER_STATISTICS

 

optval Type

Get/Set

Winsock Version

Description

RM_RECEIVER_STATS

Both

2+

Retrieves session statistics on a receiver socket

 

This option retrieves an RM_SENDER_STATS structure, which contains various network statistics for the session. This structure is defined as:

 

typedef struct _RM_RECEIVER_STATS

{

    ULONGLONG   NumODataPacketsReceived; // # OData sequences received

    ULONGLONG   NumRDataPacketsReceived; // # RData sequences received

    ULONGLONG   NumDuplicateDataPackets; // # RData sequences received

    ULONGLONG   DataBytesReceived;      // # client data bytes received out so far

    ULONGLONG   TotalBytesReceived;     // SPM, OData and RData bytes

    ULONGLONG   RateKBitsPerSecOverall; // internally calculated Receive-rate from the beginning

    ULONGLONG   RateKBitsPerSecLast;    // Receive-rate calculated every

                                                            // INTERNAL_RATE_CALCULATION_FREQUENCY

    ULONGLONG   TrailingEdgeSeqId;      // smallest (oldest) sequence Id in the window

    ULONGLONG   LeadingEdgeSeqId;       // largest (newest) Sequence Id in the window

    ULONGLONG   AverageSequencesInWindow;

    ULONGLONG   MinSequencesInWindow;

    ULONGLONG   MaxSequencesInWindow;

 

    ULONGLONG   FirstNakSequenceNumber; // # First Outstanding NAK

    ULONGLONG   NumPendingNaks;         // # Sequences waiting for NCFs

    ULONGLONG   NumOutstandingNaks;     // # Sequences for which

                                        // NCFs have been received, but no RDATA

    ULONGLONG   NumDataPacketsBuffered; // # Data packets currently buffered by transport

    ULONGLONG   TotalSelectiveNaksSent; // # Selective NAKs sent so far

    ULONGLONG   TotalParityNaksSent;    // # Parity NAKs sent so far

} RM_RECEIVER_STATS;

 

The comments for each field from the header file explain the structure so we won't repeat them.

 

IPPROTO_TCP Option Level

 

There is only one option belonging to the IPPROTO_TCP level. It is valid only for sockets that are stream sockets (SOCK_STREAM) and belong to family AF_INET. This option is available on all versions of Winsock and is supported on all Windows platforms.

 

TCP_NODELAY

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, the Nagle algorithm is disabled on the socket.

 

To increase performance and throughput by minimizing overhead, the system implements the Nagle algorithm. When an application requests to send a chunk of data, the system might hold on to that data for a while and wait for other data to accumulate before actually sending it on the wire. Of course, if no other data accumulates in a given period of time, the data will be sent regardless. This results in more data in a single TCP packet, as opposed to smaller chunks of data in multiple TCP packets. The overhead is that the TCP header for each packet is 20 bytes long. Sending a couple bytes here and there with a 20-byte header is wasteful. The other part of this algorithm is the delayed acknowledgments. Once a system receives TCP data it must send an ACK to the peer. However, the host will wait to see if it has data to send to the peer so that it can piggyback the ACK on the data to be sent, resulting in one less packet on the network.

The purpose of this option is to disable the Nagle algorithm because its behavior can be detrimental in a few cases. This algorithm can adversely affect any network application that sends relatively small amounts of data and expects a timely response. A classic example is Telnet. Telnet is an interactive application that allows the user to log on to a remote machine and send it commands. Typically, the user hits only a few keystrokes per second. The Nagle algorithm would make such a session seem sluggish and unresponsive.

 

NSPROTO_IPX Option Level

 

The socket options in this section are Microsoft-specific extensions to the Window IPX/SPX Windows Sockets interface, provided for use as necessary for compatibility with existing applications. They are otherwise not recommended because they are guaranteed to work over only the Microsoft IPX/SPX stack. An application that uses these extensions might not work over other IPX/SPX implementations. These options are defined in WSNWLINK.H, which should be included after WINSOCK.H and WSIPX.H.

 

IPX_PTYPE

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

Gets or sets the IPX packet type

 

This option gets or sets the IPX packet type. The value specified in the optval argument will be set as the packet type on every IPX packet sent from this socket. The optval parameter is an integer.

 

IPX_FILTERPTYPE

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

Gets or sets the IPX packet type to filter on

 

This option gets or sets the receive filter packet type. Only IPX packets with a packet type equal to the value specified in the optval argument are returned on any receive call; packets with a packet type that does not match are discarded.

 

IPX_STOPFILTERPTYPE

 

optval Type

Get/Set

Winsock Version

Description

int

Set only

1+

Removes the filter on the given IPX packet

 

You can use this option to stop filtering on packet types that are set with the IPX_FILTERPTYPE option.

 

IPX_DSTYPE

 

optval Type

Get/Set

Winsock Version

Description

int

Both

1+

Sets or gets the value of the datastream field in the SPX header

 

This option gets or sets the value of the datastream field in the SPX header of every packet sent.

 

IPX_EXTENDED_ADDRESS

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, enables extended addressing on IPX packets

 

This option enables or disables extended addressing. On sends, it adds the element unsigned char sa_ptype to the SOCKADDR_IPX structure, making the total length of the structure 15 bytes. On receives, the option adds both the sa_ptype and unsigned char sa_flags elements to the SOCKADDR_IPX structure, making the total length 16 bytes. The current bits defined in sa_flags are:

 

  1. 0x01 - The received frame was sent as a broadcast.
  2. 0x02 - The received frame was sent from this machine.

 

IPX_RECVHDR

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, returns IPX header with receive call

 

If this option is set to TRUE, any Winsock receive call returns the IPX header along with the data.

 

IPX_MAXSIZE

 

optval Type

Get/Set

Winsock Version

Description

int

Get only

1+

Returns the maximum IPX datagram size

 

Calling getsockopt() with this option returns the maximum IPX datagram size possible.

 

IPX_ADDRESS

 

optval Type

Get/Set

Winsock Version

Description

IPX_ADDRESS_DATA

Get only

1+

Returns information regarding an IPX-capable adapter

 

This option queries for information about a specific adapter that IPX is bound to. In a system with n adapters, the adapters are numbered 0 through n - 1. To find the number of IPX-capable adapters on the system, use the IPX_MAX_ADAPTER_NUM option with getsockopt() or call IPX_ADDRESS with increasing values of adapternum until it fails. The optval parameter points to an IPX_ADDRESS_DATA structure defined as:

 

typedef struct _IPX_ADDRESS_DATA

{

    INT     adapternum;  // Input: 0-based adapter number

    UCHAR   netnum[4];   // Output: IPX network number

    UCHAR   nodenum[6];  // Output: IPX node address

    BOOLEAN wan;         // Output: TRUE = adapter is on a WAN link

    BOOLEAN status;      // Output: TRUE = WAN link is up (or adapter is not WAN)

    INT     maxpkt;      // Output: max packet size, not including IPX header

    ULONG   linkspeed;   // Output: link speed in 100 bytes/sec (i.e., 96 == 9600 bps)

} IPX_ADDRESS_DATA, *PIPX_ADDRESS_DATA;

 

IPX_GETNETINFO

 

optval Type

Get/Set

Winsock Version

Description

IPX_NETNUM_DATA

Get only

1+

Returns information about a specific IPX network number

 

This option obtains information about a specific IPX network number. If the network is in IPX's cache, the option returns the information directly; otherwise, it issues RIP requests to find it. The optval parameter points to a valid IPX_NETNUM_DATA structure defined as:

 

typedef struct _IPX_NETNUM_DATA

{

    UCHAR  netnum[4];  // Input: IPX network number

    USHORT hopcount;   // Output: hop count to this network, in machine order

    USHORT netdelay;   // Output: tick count to this network, in machine order

    INT    cardnum;    // Output: 0-based adapter number used

                       // to route to this net; can be used as adapternum input to IPX_ADDRESS

    UCHAR  router[6];  // Output: MAC address of the next hop router,

                       // zeroed if the network is directly attached

} IPX_NETNUM_DATA, *PIPX_NETNUM_DATA;

 

IPX_GETNETINFO_NORIP

 

optval Type

Get/Set

Winsock Version

Description

IPX_NETNUM_DATA

Both

1+

If TRUE, do not fragment IP datagrams.

 

This option is similar to IPX_GETNETINFO except that it does not issue RIP requests. If the network is in IPX's cache, it returns the information; otherwise, it fails. (See also IPX_RERIPNETNUMBER, which always issues RIP requests.) Like IPX_GETNETINFO, this option requires passing an IPX_NETNUM_DATA structure as the optval parameter.

 

IPX_SPXGETCONNECTIONSTATUS

 

optval Type

Get/Set

Winsock Version

Description

IPX_SPXCONNSTATUS_DATA

Get only

1+

Returns information about a connected SPX socket

 

This option returns information on a connected SPX socket. The optval parameter points to an IPX_SPXCONNSTATUS_DATA structure defined below. All numbers are in network (high to low) byte order.

 

typedef struct _IPX_SPXCONNSTATUS_DATA

{

    UCHAR  ConnectionState;

    UCHAR  WatchDogActive;

    USHORT LocalConnectionId;

    USHORT RemoteConnectionId;

    USHORT LocalSequenceNumber;

    USHORT LocalAckNumber;

    USHORT LocalAllocNumber;

    USHORT RemoteAckNumber;

    USHORT RemoteAllocNumber;

    USHORT LocalSocket;

    UCHAR  ImmediateAddress[6];

    UCHAR  RemoteNetwork[4];

    UCHAR  RemoteNode[6];

    USHORT RemoteSocket;

    USHORT RetransmissionCount;

    USHORT EstimatedRoundTripDelay; /* In milliseconds */

    USHORT RetransmittedPackets;

    USHORT SuppressedPacket;

} IPX_SPXCONNSTATUS_DATA, *PIPX_SPXCONNSTATUS_DATA;

 

IPX_ADDRESS_NOTIFY

 

optval Type

Get/Set

Winsock Version

Description

IPX_ADDRESS_DATA

Get only

1+

Asynchronously notifies when the status of an IPX adapter changes

 

This option submits a request to be notified when the status of an adapter that IPX is bound to changes, which typically occurs when a WAN line goes up or down. This option requires the caller to submit an IPX_ADDRESS_DATA structure as the optval parameter. The exception, however, is that the IPX_ADDRESS_DATA structure is followed immediately by a handle to an unsignaled event. The following pseudo-code illustrates one method for calling this option.

 

char  buff[sizeof(IPX_ADDRESS_DATA) + sizeof(HANDLE)];

IPX_ADDRESS_DATA *ipxdata;

HANDLE *hEvent;

 

ipxdata = (IPX_ADDRESS_DATA *)buff;

hEvent = (HANDLE *)(buff + sizeof(IPX_ADDRESS_DATA));

ipxdata->adapternum = 0;  // Set to the appropriate adapter

*hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

setsockopt(s, NSPROTO_IPX, IPX_ADDRESS_NOTIFY, (char *)buff, sizeof(buff));

 

When the getsockopt query is submitted, it completes successfully. However, the IPX_ADDRESS_DATA structure pointed to by optval will not be updated at that point. Instead, the request is queued internally inside the transport, and when the status of an adapter changes, IPX locates a queued getsockopt query and fills in all the fields in the IPX_ADDRESS_DATA structure. It then signals the event pointed to by the handle in the optval buffer. If multiple getsockopt calls are submitted at once, different events must be used. The event is used because the call needs to be asynchronous; getsockopt does not currently support this.

In the current implementation, the transport signals only one queued query for each status change. Therefore, only one service that uses a queued query should run at once.

 

IPX_MAX_ADAPTER_NUM

 

optval Type

Get/Set

Winsock Version

Description

int

Get only

1+

Returns the number of IPX adapters present

 

This option returns the number of IPX-capable adapters present on the system. If this call returns n adapters, the adapters are numbered 0 through n – 1.

 

IPX_RERIPNETNUMBER

 

optval Type

Get/Set

Winsock Version

Description

IPX_NETNUM_DATA

Get only

1+

Returns information about a network number

 

This option is related to IPX_GETNETINFO except that it forces IPX to reissue RIP requests even if the network is in its cache (but not if it is directly attached to that network). Like IPX_GETNETINFO, this option requires passing an IPX_NETNUM_DATA structure as the optval parameter.

 

IPX_RECEIVE_BROADCAST

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Set only

1+

If TRUE, do not receive broadcast IPX packets.

 

By default, an IPX socket is capable of receiving broadcast packets. Applications that do not need to receive broadcast packets should set this option to FALSE, which can cause better system performance. Note, however, that setting the option to FALSE does not necessarily cause broadcasts to be filtered for the application.

 

IPX_IMMEDIATESPXACK

 

optval Type

Get/Set

Winsock Version

Description

BOOL

Both

1+

If TRUE, do not delay sending ACKs on SPX connections.

 

If you set this option to true, acknowledgment packets will not be delayed for SPX connections. Applications that do not tend to have back-and-forth traffic over SPX should set this, it increases the number of ACKs sent but prevents slow performance as a result of delayed acknowledgments.

 

Ioctlsocket(), WSAIoctl(), and WSANSPIoctl()

 

The socket ioctl functions are used to control the behavior of I/O on the socket, as well as to obtain information about I/O pending on that socket. The first function, ioctlsocket(), originated in the Winsock 1 specification and is declared as:

 

int ioctlsocket (

    SOCKET s,

    long cmd,

    u_long FAR *argp

);

 

The parameter s is the socket descriptor to act on, and cmd is a predefined flag for the I/O control command to execute. The last parameter, argp, is a pointer to a variable specific to the given command. When each command is described, the type of the required variable is given. Winsock 2 introduced a new ioctl function that adds quite a few new options. First, it breaks the single argp parameter into a set of input parameters for values passed into the function and a set of output parameters used to return data from the call. In addition, the function call can use overlapped I/O. This function is WSAIoctl(), which is defined as:

 

int WSAIoctl(

    SOCKET s,

    DWORD dwIoControlCode,

    LPVOID lpvInBuffer,

    DWORD cbInBuffer,

    LPVOID lpvOutBuffer,

    DWORD cbOutBuffer,

    LPDWORD lpcbBytesReturned,

    LPWSAOVERLAPPED lpOverlapped,

    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

);

 

The first two parameters are the same as those in ioctlsocket. The second two, lpvInBuffer and cbInBuffer, describe the input parameters. The lpvInBuffer parameter is a pointer to the value passed in, and cbInBuffer is the size of that data in bytes. Likewise, lpvOutBuffer and cbOutBuffer are used for any data returned from the call. The lpvOutBuffer parameter points to a data buffer in which any information returned is placed. The cbOutBuffer parameter is the size in bytes of the buffer passed in as lpvOutBuffer. Note that some calls might use only input or output parameters, and others will use both. The seventh parameter, lpcbBytesReturned, is the number of bytes actually returned. The last two parameters, lpOverlapped and lpCompletionRoutine, are used when calling this function with overlapped I/O.

Lastly, a new ioctl function, WSANSPIoctl(), has been introduced for Windows XP. This function is used exclusively for making I/O control calls to name space providers. The function is defined as:

 

int WSANSPIoctl(

            HANDLE hLookup,

            DWORD dwControlCode,

            LPVOID lpvInBuffer,

            DWORD cbInBuffer,

            LPVOID lpvOutBuffer,

            DWORD cbOutBuffer,

            LPDWORD lpcbBytesReturned,

            LPWSACOMPLETION lpCompletion

);

 

The parameters to this function are the same as WSAIoctl() except for hLookup and lpCompletion. The handle passed into this function is the handle returned from WSALookupServiceBegin(). This handle identifies a name space query to a particular name space provider. The lpCompletion parameter specifies how the application should be notified if there is a change to the name space provider or query. This new ioctl function is used by the Network Location Awareness (NLA) service, which is described in another chapter.

 

 

 


< SOL/SO & IRLMP | Socket Options & IOCTLs Main | FIONBIO, FIONREAD & SIO >