From f932aee000ca6cc9ddc0cf09564d43f355ed8e2e Mon Sep 17 00:00:00 2001 From: David Scott Date: Fri, 4 Aug 2017 17:04:03 +0100 Subject: [PATCH] Windows uses SOCK_RAW for ICMP sockets The MSDN reference[1] says: > An example of the first type of socket is a socket for the ICMP protocol > (IP protocol type = 1) or the ICMPv6 protocol (IP procotol type = 58). [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms740548(v=vs.85).aspx Signed-off-by: David Scott --- src/stack-unix/icmpv4_socket.ml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/stack-unix/icmpv4_socket.ml b/src/stack-unix/icmpv4_socket.ml index cdc1bb942..04b792de4 100644 --- a/src/stack-unix/icmpv4_socket.ml +++ b/src/stack-unix/icmpv4_socket.ml @@ -9,6 +9,13 @@ type t = unit type error = [ `Ip of string ] let pp_error ppf (`Ip s) = Fmt.string ppf s +let is_win32 = Sys.os_type = "Win32" + +let sock_icmp = + (* Windows uses SOCK_RAW protocol 1 for ICMP + Unix uses SOCK_DGRAM protocol 1 for ICMP *) + if is_win32 then Lwt_unix.SOCK_RAW else Lwt_unix.SOCK_DGRAM + let ipproto_icmp = 1 (* according to BSD /etc/protocols *) let port = 0 (* port isn't meaningful in this context *) @@ -29,7 +36,7 @@ let write _t ~dst buf = let flags = [] in let ipproto_icmp = 1 in (* according to BSD /etc/protocols *) let port = 0 in (* port isn't meaningful in this context *) - let fd = socket PF_INET SOCK_DGRAM ipproto_icmp in + let fd = socket PF_INET sock_icmp ipproto_icmp in let in_addr = Unix.inet_addr_of_string (Ipaddr.V4.to_string dst) in let sockaddr = ADDR_INET (in_addr, port) in Lwt.catch (fun () -> @@ -61,7 +68,7 @@ let input t ~src ~dst:_ buf = | _, _ -> Lwt.return_unit let listen _t addr fn = - let fd = Lwt_unix.(socket PF_INET SOCK_DGRAM) ipproto_icmp in + let fd = Lwt_unix.socket PF_INET sock_icmp ipproto_icmp in let sa = Lwt_unix.ADDR_INET (Unix.inet_addr_of_string (Ipaddr.V4.to_string addr), port) in Lwt_unix.bind fd sa >>= fun () -> Log.debug (fun f -> f "Bound ICMP file descriptor to %a" pp_sockaddr sa);