< SOL/SO & IRLMP | Socket Options & IOCTLs Main | FIONBIO, FIONREAD & SIO >
What do we have in this chapter 7 part 2?
|
IP_OPTIONS
This flag allows you to set various IP options within the IP header. Some of the possible options are:
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.
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.
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.
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.
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));
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
Socket options of the IPPROTO_RM level are used by the reliable multicast transport. These options are declared in wsrm.h.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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.
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;
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;
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.
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;
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.
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.
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.
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.
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.
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 >