4

I'm doing some socket programming that I'm trying to make cross-platform compatible. For Windows systems, I'm including the following headers:

#include <winsock2.h>
#include <ws2tcpip.h>

When I tried to compile my application on Windows, I got errors about the following constants' being undefined:

IP_RECVOPTS
IP_RECVRETOPTS

I thought that odd, because I thought those were pretty common socket options, but perhaps I'm wrong. Either way, sure enough, they're not listed anywhere in the Windows socket documentation.

The documentation in a Linux distro's in.h says the following about these constants:

IP_RECVOPTS      /* bool; Receive all IP options w/datagram.  */
IP_RECVRETOPTS   /* bool; Receive IP options for response.  */

In that distro's in.h, the defined value of the first one appears to be 6, while the defined value of the second one appears to be 7.

So, my questions:

  1. Are there equivalent constants in Windows sockets for replacing these two constants (or, perhaps, do I just need to include some other header)?
  2. If not, is the receiving of IP options even possible in Windows sockets?
  3. If so, is it safe for me to hard-code these values on Windows systems to 6 and 7, respectively, or should they be some other value?

UPDATE 1

I continued my Google research today. I found these two interesting tidbits. I don't know whether they help me. The first is the Windows Runtime (WinRT) Socket Address header (WinRTSockAddr.h) from the MixedRealityToolkit repository on Microsoft's official GitHub account. It contains the following:

#define IP_RECVOPTS     6
#define IP_RETOPTS      7

This aligns with *nix values I've seen elsewhere (I've commonly seen IP_RETOPTS aliased to IP_RECVRETOPTS). But then there's this alleged Windows Sockets helper header from the "Geek Research Lab"'s GitHub account. I've no idea if it has any credibility, but it has different values for these constants:

#define IP_RECVOPTS 5 /* bool; receive all IP opts w/dgram */
#define IP_RECVRETOPTS 6 /* bool; receive IP opts for response */
#define IP_RECVDSTADDR 7 /* bool; receive IP dst addr w/dgram */
#define IP_RETOPTS 8 /* ip_opts; set/get IP options */

That's contradictory on all fronts: values and the aliasing of IP_RETOPTS to IP_RECVRETOPTS. :-/

Nick Williams
  • 2,864
  • 5
  • 29
  • 43
  • The header from WinRT appears to be an external product and certainly from an external supplier. The 'alleged' header doesn't even compile. You can't rely on either of these. Official Microsoft documentation is [here](https://learn.microsoft.com/en-us/windows/desktop/winsock/ipproto-ip-socket-options), and it doesn't contain these constants. – user207421 Jan 31 '19 at 05:20
  • Are there specific IP options you're interested in? There may be other ways of getting them. – dbush Jan 31 '19 at 13:58
  • Please provide a code so we know what options you require and what is the goal of the process. We might be able to help; otherwise, there is no in-place replacement for these constants AFAIK. https://learn.microsoft.com/en-us/windows/desktop/winsock/ipproto-ip-socket-options – Soroush Falahati Feb 01 '19 at 01:02

2 Answers2

1

The only somewhat portable standard for accessing IP (as well as TCP and UDP) options is via the ancillary data parameters of sendmsg and recvmsg.

Unfortunately while having access is standardized, the exact details of what options are available can still vary between OSes.

On Linux, see the cmsg man page and note:

CONFORMING TO

This ancillary data model conforms to the POSIX.1g draft, 4.4BSD- Lite, the IPv6 advanced API described in RFC 2292 and SUSv2. CMSG_ALIGN() is a Linux extension.

By comparison, the man page describing IP_RECVOPTS has no "CONFORMING TO" section.

The similar Windows documentation page is "IPPROTO_IP Socket Options" on MSDN

In the Windows documentation for WSARecvMsg and WSASendMsg, there's the following note:

based on the Posix.1g specification for the msghdr structure

The documentation for _WSAMSG lists the ancillary data available from Winsock.


The POSIX documentation is here

Unfortunately for portability:

The system documentation shall specify the cmsg_type definitions for the supported protocols.

which is to say, the ancillary data actually available is not portable, because it's not specified by POSIX and/or Single Unix Specification.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
-1

Are there equivalent constants in Windows sockets for replacing these two constants (or, perhaps, do I just need to include some other header)?

No. Unfortunately, this wouldn't be the first time that Windows is slow to implement parts of a particular standard or an RFC. Taking a look at socket options, for example, IP_RECVTTL was added only recently, for Windows 10. So maybe if you wait long enough, you may live to see the options you want supported on Windows? The code you have seen seems to be copy-pasted from some other, non-Windows code. In the case of RakNet, note that WinRTSockAddr.h is only used for WINDOWS_STORE_RT support, which is currently limited.

If not, is the receiving of IP options even possible in Windows sockets?

No, it does not seem to be. At least I'm not aware of such capability.

If so, is it safe for me to hard-code these values on Windows systems to 6 and 7, respectively, or should they be some other value?

No, it's probably not safe to hard-code the values. At best, such option values would be ignored, but they could be misinterpreted and result in unwanted behavior.

Since you indicated that you aim to make your code cross-platform, you will likely have to settle for the intersection of features that are supported on all the platforms that you want to support.

mnistic
  • 10,866
  • 2
  • 19
  • 33
  • 1
    What particular standard or RFC do you claim this is? Before trash-talking Microsoft, you should check whether perhaps they did follow the standard, and your code is non-portable. – Ben Voigt Feb 03 '19 at 01:00
  • RFC 791. I suppose the language says that the transmission of options in every datagram is optional, so it could be interpreted to mean that this flag is not required. Is that your point? – mnistic Feb 03 '19 at 03:59
  • 1
    No. What we're discussing here is the sockets API, not the wire protocol. Normally the TCP/IP stack itself processes (both synthesizing and consuming) the RFC 791 options found on the wire, without the application ever finding out. These socket API options ("sockopt") tell the TCP/IP stack to include options in the payload data passed to the application. One can perfectly well support the (IP, TCP, UDP) options in the TCP/IP stack without supporting these sockopt constants. – Ben Voigt Feb 03 '19 at 04:02
  • The division of responsibility between TCP/IP stack and application is not specified by RFC 791. – Ben Voigt Feb 03 '19 at 04:03
  • Well, if the low level protocol supports something that's not exposed to software through an API, to me that's a problem. – mnistic Feb 03 '19 at 04:18
  • Well, Windows chose to put most of the RFC 791 options (like TCP sliding window size, QOS markings, etc) under the control of the PC owner via registry configuration. If the owner is master and applications are guests on the machine, that makes sense. If applications are master and the owner is limited, well that sounds like DRM. – Ben Voigt Feb 03 '19 at 04:31
  • FWIW, RFC 3542 does cover this at the Sockets API level, only for IPv6, and Windows implements it. – Ben Voigt Feb 03 '19 at 04:35
  • Can you enforce transmission of options through the registry? If not, can Microsoft claim conformance for having implemented a feature you can't use? BTW are you making the claim that this is actually implemented in the TCP/IP stack? – mnistic Feb 04 '19 at 14:43
  • If you click the link to `_WSAMSG` documentation in my answer, you'll see that the RFC 3542 capabilities are there -- although there's some gratuitous source code incompatibility :(. – Ben Voigt Feb 04 '19 at 14:49
  • I see. I suppose `IPV6_DSTOPTS` is what the OP wants, but for IPv6. It seems you think that my claim is inaccurate because there is no such application-level RFC for IPv4, but I'll let the answer stand for now because I still think it makes a good point -- I think if they implemented all of 791 they would have made those options configurable somehow by now. I didn't mean to trash-talk, I didn't realize that stating that Microsoft is sometimes slow to comply with standards was controversial. My biggest gripe is with the C compiler, but there are others. – mnistic Feb 04 '19 at 23:17