It seems sendto() can return EACCES for UDP as well; the current
man page in git only says it can return EACCES for Unix sockets.
I was able to make sendto() return EACCES if I try to send from
192.168.1.1/24 to 192.168.1.0. I think the relevant code (in
kernel 2.6.38, but also present in 2.6.7 and 2.6.32, the 2 kernels
we use) is this (net/ipv4/udp.c, udp_sendmsg()):
910 err = -EACCES;
911 if ((rt->rt_flags & RTCF_BROADCAST) &&
912 !sock_flag(sk, SOCK_BROADCAST))
913 goto out;
So I guess if the kernel finds a route to the destination and
it's a broadcast route (and the socket doesn't have the broadcast
flag), then it returns EACCES.
I can verify the behavior with a very simple program (attached).
I've run it on my Ubuntu 10.10 (2.6.35 kernel) and got this:
stefan@spuiu-vml2:~/src/test/broadcast$ ./broadcast_test 10.205.20.94
10.205.20.1
sendto() returned 4
stefan@spuiu-vml2:~/src/test/broadcast$ ./broadcast_test 10.205.20.94
10.205.20.0
sendto() returned negative, errno: 13/Permission denied
(10.205.20.94 is my local IP, of course).
=====
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int sock;
if (argc < 2) {
printf("Usage: %s local_address destination_address\n", argv[0]);
exit(1);
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("socket");
return -1;
}
struct sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(1234);
local_addr.sin_addr.s_addr = inet_addr(argv[1]);
int ret = bind(sock, (struct sockaddr *) &local_addr, sizeof(local_addr));
if (ret < 0) {
perror("bind");
return -1;
}
struct sockaddr_in remote_addr;
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(1234);
remote_addr.sin_addr.s_addr = inet_addr(argv[2]);
ret = sendto(sock, "blah", 4, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
if (ret < 0) {
printf("sendto() returned negative, errno: %d/%m\n", errno);
}
else {
printf("sendto() returned %d\n", ret);
}
return 0;
}
=====
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
The man pages were rather inconsistent in the use of "Unix"
versus "UNIX". Let's go with the trademark usage.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This patch fixes the type of msg_controllen in the struct msghdr
definition given in send.2 and recv.2 to match the definition in
glibc and the kernel.
Signed-off-by: Michael Kerrisk <mtk@konstanz.(none)>
The tendency in English, as prescribed in style guides like
Chicago MoS, is towards removing hyphens after prefixes
like "non-" etc.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
For a non-blocking socket, POSIX.1-2001/2008 allow either
EAGAIN or EWOULDBLOCK to be returned in cases where a call
would have blocked. Although these constants are defined
with the same value on most Linux architectures (PA-RISC
is the exception), POSIX.1 does not require them to have
the same value. Therefore, a portable application using
the sockets API should test for both errors when checking
this case.
(NB POSIX.1 only mentions EWOULDBLOCK in the context of
the sockets interfaces.)
Change made after a note cross-posted on linux-arch@vger,
http://thread.gmane.org/gmane.linux.debian.ports.hppa/5615
and a suggestion for write(2) from Carlos O'Donell
Reported-by: Carlos O'Donell <carlos@systemhalted.org>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Many sockets man pages use the name 'sockfd' already.
For consistency, changes the others to do so as well.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Many pages still mention use of the obsolete sysctl(2) system
call, or used the term "sysctls"; rewrite these mentions to
instead be in terms of /proc interfaces.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>