Socket定数に無い定数を無理やり使う

# 事の発端
Windows 7 で IP層のフラグ Don't Fragmentation を OFF にしたいと思い。以下のように設定。

```rb
require 'socket'

s0 = TCPServer.open("", 12345)
p s0.setsockopt(:IP, Socket::IP_DONTFRAG, 0) # => uninitialized constant Socket::IP_DONTFRAG (NameError)
```

`Socket::IP_TTL`はうまくいくので、指定が間違っているのではなさそう。

```rb
p s0.setsockopt(:IP, Socket::IP_TTL, 255) # => 0
```

# 定数が本当にないのか？

```rb
require 'socket'
require 'pp'

pp Socket.constants # => [
 :Option,
 :Constants,
 :SOCK_STREAM,
 :SOCK_DGRAM,
 :SOCK_RAW,
 :SOCK_RDM,
 :SOCK_SEQPACKET,
 :AF_UNSPEC,
 :PF_UNSPEC,
 :AF_INET,
 :PF_INET,
 :AF_INET6,
 :PF_INET6,
 :AF_UNIX,
 :PF_UNIX,
 :AF_IPX,
 :PF_IPX,
 :AF_APPLETALK,
 :PF_APPLETALK,
 :AF_IMPLINK,
 :PF_IMPLINK,
 :AF_PUP,
 :PF_PUP,
 :AF_CHAOS,
 :PF_CHAOS,
 :AF_NS,
 :PF_NS,
 :AF_ISO,
 :PF_ISO,
 :AF_OSI,
 :PF_OSI,
 :AF_ECMA,
 :PF_ECMA,
 :AF_DATAKIT,
 :PF_DATAKIT,
 :AF_CCITT,
 :PF_CCITT,
 :AF_SNA,
 :PF_SNA,
 :AF_DLI,
 :PF_DLI,
 :AF_LAT,
 :PF_LAT,
 :AF_HYLINK,
 :PF_HYLINK,
 :AF_NETBIOS,
 :AF_ATM,
 :PF_ATM,
 :AF_MAX,
 :PF_MAX,
 :MSG_OOB,
 :MSG_PEEK,
 :MSG_DONTROUTE,
 :MSG_WAITALL,
 :SOL_SOCKET,
 :IPPROTO_IP,
 :IPPROTO_ICMP,
 :IPPROTO_IGMP,
 :IPPROTO_GGP,
 :IPPROTO_TCP,
 :IPPROTO_PUP,
 :IPPROTO_UDP,
 :IPPROTO_IDP,
 :IPPROTO_ND,
 :IPPROTO_AH,
 :IPPROTO_DSTOPTS,
 :IPPROTO_ESP,
 :IPPROTO_FRAGMENT,
 :IPPROTO_HOPOPTS,
 :IPPROTO_ICMPV6,
 :IPPROTO_IPV6,
 :IPPROTO_NONE,
 :IPPROTO_ROUTING,
 :IPPROTO_RAW,
 :IPPROTO_MAX,
 :IPPORT_RESERVED,
 :IPPORT_USERRESERVED,
 :INADDR_ANY,
 :INADDR_BROADCAST,
 :INADDR_LOOPBACK,
 :INADDR_UNSPEC_GROUP,
 :INADDR_ALLHOSTS_GROUP,
 :INADDR_MAX_LOCAL_GROUP,
 :INADDR_NONE,
 :IP_OPTIONS,
 :IP_HDRINCL,
 :IP_TOS,
 :IP_TTL,
 :IP_MULTICAST_IF,
 :IP_MULTICAST_TTL,
 :IP_MULTICAST_LOOP,
 :IP_ADD_MEMBERSHIP,
 :IP_DROP_MEMBERSHIP,
 :IP_PKTINFO,
 :IP_UNBLOCK_SOURCE,
 :IP_BLOCK_SOURCE,
 :IP_ADD_SOURCE_MEMBERSHIP,
 :IP_DROP_SOURCE_MEMBERSHIP,
 :SO_DEBUG,
 :SO_REUSEADDR,
 :SO_TYPE,
 :SO_ERROR,
 :SO_DONTROUTE,
 :SO_BROADCAST,
 :SO_SNDBUF,
 :SO_RCVBUF,
 :SO_KEEPALIVE,
 :SO_OOBINLINE,
 :SO_LINGER,
 :SO_RCVLOWAT,
 :SO_SNDLOWAT,
 :SO_RCVTIMEO,
 :SO_SNDTIMEO,
 :SO_ACCEPTCONN,
 :SO_USELOOPBACK,
 :TCP_NODELAY,
 :EAI_AGAIN,
 :EAI_BADFLAGS,
 :EAI_FAIL,
 :EAI_FAMILY,
 :EAI_MEMORY,
 :EAI_NODATA,
 :EAI_NONAME,
 :EAI_SERVICE,
 :EAI_SOCKTYPE,
 :AI_PASSIVE,
 :AI_CANONNAME,
 :AI_NUMERICHOST,
 :NI_MAXHOST,
 :NI_MAXSERV,
 :NI_NOFQDN,
 :NI_NUMERICHOST,
 :NI_NAMEREQD,
 :NI_NUMERICSERV,
 :NI_DGRAM,
 :SHUT_RD,
 :SHUT_WR,
 :SHUT_RDWR,
 :IPV6_JOIN_GROUP,
 :IPV6_LEAVE_GROUP,
 :IPV6_MULTICAST_HOPS,
 :IPV6_MULTICAST_IF,
 :IPV6_MULTICAST_LOOP,
 :IPV6_UNICAST_HOPS,
 :IPV6_HOPLIMIT,
 :IPV6_PKTINFO,
 :INET_ADDRSTRLEN,
 :INET6_ADDRSTRLEN,
 :SOMAXCONN,
 :UDPSource,
 :WaitReadable,
 :WaitWritable,
 :SEEK_SET,
 :SEEK_CUR,
 :SEEK_END,
 :RDONLY,
 :WRONLY,
 :RDWR,
 :APPEND,
 :CREAT,
 :EXCL,
 :NONBLOCK,
 :TRUNC,
 :BINARY,
 :LOCK_SH,
 :LOCK_EX,
 :LOCK_UN,
 :LOCK_NB,
 :NULL,
 :FNM_NOESCAPE,
 :FNM_PATHNAME,
 :FNM_DOTMATCH,
 :FNM_CASEFOLD,
 :FNM_EXTGLOB,
 :FNM_SYSCASE]
```

... ない。何故ないのかは不明。

# setsockopt に Integer 直接入れたら行けんじゃね？

rubyのリファレンスの`Socket#setsockopt`を見てみると。
setsockopt(2)を参照してくださいとの記載が。見ると、引数は`int`の模様。
rubyから整数を渡してやったらそのまま設定されるんじゃないか説浮上。

# Windows の Don't Fragment 定数値

MSDNに記載あり。https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms738586(v=vs.85).aspx

`IP_DONT_FRAGMENT`がそれっぽい。定義は`Winsock2.h`を見ろと。ふむふむ。

色々検索してサイトを渡り歩いていると以下のサイトに出会う。

http://www.geekpage.jp/programming/winsock/tips-setsockopt.php

なんか不穏なことが書いてあるけど、9か14を使えばいいのね。

# ruby は ws2tcpip.h を使っている。

9か14を使えってのはわかったけど、どっち使うか。

ruby の github リポジトリを眺めてると `ws2tcpip.h` を使ってたので、14が正解。
https://github.com/ruby/ruby/blob/f150a381db5b51552b714e9a5893654cd056962c/include/ruby/win32.h#L42


# setsockopt に Integer を直接入れてみる。

```rb
require 'socket'

s0 = TCPServer.open("", 12345)
p s0.setsockopt(:IP, 14, 0) # => 0
```

いけたっぽい？