Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1e35966e
Commit
1e35966e
authored
Jul 04, 2022
by
Paul Gofman
Committed by
Alexandre Julliard
Jul 18, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support SOCK_RAW / IPPROTO_ICMP fallback over SOCK_DGRAM.
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
parent
86f08493
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
125 additions
and
1 deletion
+125
-1
socket.c
dlls/ntdll/unix/socket.c
+108
-1
sock.c
server/sock.c
+17
-0
No files found.
dlls/ntdll/unix/socket.c
View file @
1e35966e
...
...
@@ -115,6 +115,7 @@ struct async_recv_ioctl
DWORD
*
ret_flags
;
int
unix_flags
;
unsigned
int
count
;
BOOL
icmp_over_dgram
;
struct
iovec
iov
[
1
];
};
...
...
@@ -566,6 +567,89 @@ static int wow64_translate_control( const WSABUF *control64, struct afd_wsabuf_3
return
1
;
}
struct
ip_hdr
{
BYTE
v_hl
;
/* version << 4 | hdr_len */
BYTE
tos
;
UINT16
tot_len
;
UINT16
id
;
UINT16
frag_off
;
BYTE
ttl
;
BYTE
protocol
;
UINT16
checksum
;
ULONG
saddr
;
ULONG
daddr
;
};
static
ssize_t
fixup_icmp_over_dgram
(
struct
msghdr
*
hdr
,
union
unix_sockaddr
*
unix_addr
,
ssize_t
recv_len
,
NTSTATUS
*
status
)
{
unsigned
int
tot_len
=
sizeof
(
struct
ip_hdr
)
+
recv_len
;
struct
cmsghdr
*
cmsg
;
struct
ip_hdr
ip_h
;
size_t
buf_len
;
char
*
buf
;
if
(
hdr
->
msg_iovlen
!=
1
)
{
FIXME
(
"Buffer count %zu is not supported for ICMP fixup.
\n
"
,
(
size_t
)
hdr
->
msg_iovlen
);
return
recv_len
;
}
buf
=
hdr
->
msg_iov
[
0
].
iov_base
;
buf_len
=
hdr
->
msg_iov
[
0
].
iov_len
;
if
(
recv_len
+
sizeof
(
ip_h
)
>
buf_len
)
*
status
=
STATUS_BUFFER_OVERFLOW
;
if
(
buf_len
<
sizeof
(
ip_h
))
{
recv_len
=
buf_len
;
}
else
{
recv_len
=
min
(
recv_len
,
buf_len
-
sizeof
(
ip_h
)
);
memmove
(
buf
+
sizeof
(
ip_h
),
buf
,
recv_len
);
recv_len
+=
sizeof
(
ip_h
);
}
memset
(
&
ip_h
,
0
,
sizeof
(
ip_h
)
);
ip_h
.
v_hl
=
(
4
<<
4
)
|
(
sizeof
(
ip_h
)
>>
2
);
ip_h
.
tot_len
=
htons
(
tot_len
);
ip_h
.
protocol
=
1
;
ip_h
.
saddr
=
unix_addr
->
in
.
sin_addr
.
s_addr
;
for
(
cmsg
=
CMSG_FIRSTHDR
(
hdr
);
cmsg
;
cmsg
=
CMSG_NXTHDR
(
hdr
,
cmsg
))
{
if
(
cmsg
->
cmsg_level
!=
IPPROTO_IP
)
continue
;
switch
(
cmsg
->
cmsg_type
)
{
#if defined(IP_TTL)
case
IP_TTL
:
ip_h
.
ttl
=
*
(
BYTE
*
)
CMSG_DATA
(
cmsg
);
break
;
#endif
#if defined(IP_TOS)
case
IP_TOS
:
ip_h
.
tos
=
*
(
BYTE
*
)
CMSG_DATA
(
cmsg
);
break
;
#endif
#if defined(IP_PKTINFO)
case
IP_PKTINFO
:
{
struct
in_pktinfo
*
info
;
info
=
(
struct
in_pktinfo
*
)
CMSG_DATA
(
cmsg
);
ip_h
.
daddr
=
info
->
ipi_addr
.
s_addr
;
break
;
}
#endif
}
}
memcpy
(
buf
,
&
ip_h
,
min
(
sizeof
(
ip_h
),
buf_len
));
return
recv_len
;
}
static
NTSTATUS
try_recv
(
int
fd
,
struct
async_recv_ioctl
*
async
,
ULONG_PTR
*
size
)
{
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
...
...
@@ -577,7 +661,7 @@ static NTSTATUS try_recv( int fd, struct async_recv_ioctl *async, ULONG_PTR *siz
ssize_t
ret
;
memset
(
&
hdr
,
0
,
sizeof
(
hdr
)
);
if
(
async
->
addr
)
if
(
async
->
addr
||
async
->
icmp_over_dgram
)
{
hdr
.
msg_name
=
&
unix_addr
.
addr
;
hdr
.
msg_namelen
=
sizeof
(
unix_addr
);
...
...
@@ -602,9 +686,14 @@ static NTSTATUS try_recv( int fd, struct async_recv_ioctl *async, ULONG_PTR *siz
}
status
=
(
hdr
.
msg_flags
&
MSG_TRUNC
)
?
STATUS_BUFFER_OVERFLOW
:
STATUS_SUCCESS
;
if
(
async
->
icmp_over_dgram
)
ret
=
fixup_icmp_over_dgram
(
&
hdr
,
&
unix_addr
,
ret
,
&
status
);
if
(
async
->
control
)
{
if
(
async
->
icmp_over_dgram
)
FIXME
(
"May return extra control headers.
\n
"
);
if
(
in_wow64_call
())
{
char
control_buffer64
[
512
];
...
...
@@ -675,6 +764,23 @@ static BOOL async_recv_proc( void *user, ULONG_PTR *info, NTSTATUS *status )
return
TRUE
;
}
static
BOOL
is_icmp_over_dgram
(
int
fd
)
{
#ifdef linux
socklen_t
len
;
int
val
;
len
=
sizeof
(
val
);
if
(
getsockopt
(
fd
,
SOL_SOCKET
,
SO_PROTOCOL
,
(
char
*
)
&
val
,
&
len
)
||
val
!=
IPPROTO_ICMP
)
return
FALSE
;
len
=
sizeof
(
val
);
return
!
getsockopt
(
fd
,
SOL_SOCKET
,
SO_TYPE
,
(
char
*
)
&
val
,
&
len
)
&&
val
==
SOCK_DGRAM
;
#else
return
FALSE
;
#endif
}
static
NTSTATUS
sock_recv
(
HANDLE
handle
,
HANDLE
event
,
PIO_APC_ROUTINE
apc
,
void
*
apc_user
,
IO_STATUS_BLOCK
*
io
,
int
fd
,
struct
async_recv_ioctl
*
async
,
int
force_async
)
{
...
...
@@ -777,6 +883,7 @@ static NTSTATUS sock_ioctl_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
async
->
addr
=
addr
;
async
->
addr_len
=
addr_len
;
async
->
ret_flags
=
ret_flags
;
async
->
icmp_over_dgram
=
is_icmp_over_dgram
(
fd
);
return
sock_recv
(
handle
,
event
,
apc
,
apc_user
,
io
,
fd
,
async
,
force_async
);
}
...
...
server/sock.c
View file @
1e35966e
...
...
@@ -1618,6 +1618,23 @@ static int init_socket( struct sock *sock, int family, int type, int protocol )
}
sockfd
=
socket
(
unix_family
,
unix_type
,
unix_protocol
);
#ifdef linux
if
(
sockfd
==
-
1
&&
errno
==
EPERM
&&
unix_family
==
AF_INET
&&
unix_type
==
SOCK_RAW
&&
unix_protocol
==
IPPROTO_ICMP
)
{
sockfd
=
socket
(
unix_family
,
SOCK_DGRAM
,
unix_protocol
);
if
(
sockfd
!=
-
1
)
{
const
int
val
=
1
;
setsockopt
(
sockfd
,
IPPROTO_IP
,
IP_RECVTTL
,
(
const
char
*
)
&
val
,
sizeof
(
val
)
);
setsockopt
(
sockfd
,
IPPROTO_IP
,
IP_RECVTOS
,
(
const
char
*
)
&
val
,
sizeof
(
val
)
);
setsockopt
(
sockfd
,
IPPROTO_IP
,
IP_PKTINFO
,
(
const
char
*
)
&
val
,
sizeof
(
val
)
);
}
}
#endif
if
(
sockfd
==
-
1
)
{
if
(
errno
==
EINVAL
)
set_win32_error
(
WSAESOCKTNOSUPPORT
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment