UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » Networking
  • » setsockopt returns No device Found error in multicast

#1 2009-01-27 10:50 AM

epolluser
Member
Registered: 2008-01-14
Posts: 21

Re: setsockopt returns No device Found error in multicast

i am an beginner in UDP-Multicasting. I browsed through the sample code given in http://www.tack.ch/multicast/ link.
while executing the sample server and client program, setsockopt call in server.c returns -1 and sets errno to 19 i.e. No Device Found.

// JOIN multicast group on default interface
   status = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
              (const void *)&imreq, sizeof(struct ip_mreq));

I am executing server and client on separate machines. though setsockopt returns error the message sent from client is received at the server end.

Instead of using INADDR_ANY in interface, i have set the local machine IP addr (where client is running)as interface addr.
Please let me know what exactly has to be done? why is setsockopt() throwing errno = 19 though message is being sent?

Offline

#2 2009-01-27 12:20 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: setsockopt returns No device Found error in multicast

Could you post a bit more code, especially the part before where you do other things and initialize imreq? Or can it be found at that url? (No time to check it out now.)

Offline

#3 2009-01-27 01:30 PM

epolluser
Member
Registered: 2008-01-14
Posts: 21

Re: setsockopt returns No device Found error in multicast

server.c
___________________________________________________________

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXBUFSIZE 65536 // Max UDP Packet size is 64 Kbyte

int main()
{
   int sock, status, socklen;
   char buffer[MAXBUFSIZE];
   struct sockaddr_in saddr;
   struct ip_mreq imreq;

   // set content of struct saddr and imreq to zero
   memset(&saddr, 0, sizeof(struct sockaddr_in));
   memset(&imreq, 0, sizeof(struct ip_mreq));

   // open a UDP socket
   sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
   if ( sock < 0 )
     perror("Error creating socket"), exit(0);

   saddr.sin_family = PF_INET;
   saddr.sin_port = htons(4096); // listen on port 4096
   saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind socket to any interface
   status = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));

   if ( status < 0 )
     perror("Error binding socket to interface"), exit(0);

   imreq.imr_multiaddr.s_addr = inet_addr("226.0.0.1");
   //imreq.imr_interface.s_addr = INADDR_ANY; // use DEFAULT interface
===>   imreq.imr_interface.s_addr = inet_addr("x.x.x.x"); // ip of the machine on which client is running
   // JOIN multicast group on default interface
   status = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
              (const void *)&imreq, sizeof(struct ip_mreq));

   socklen = sizeof(struct sockaddr_in);

   // receive packet from socket
   status = recvfrom(sock, buffer, MAXBUFSIZE, 0, 
                     (struct sockaddr *)&saddr, &socklen);

   // shutdown socket
   shutdown(sock, 2);
   // close socket
   close(sock);

   return 0;
}

client.c
___________________________________________________________

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXBUFSIZE 65536 // Max UDP Packet size is 64 Kbyte

int main()
{
   int sock, status, socklen;
   char buffer[MAXBUFSIZE];
   struct sockaddr_in saddr;
   struct in_addr iaddr;
   unsigned char ttl = 3;
   unsigned char one = 1;

   // set content of struct saddr and imreq to zero
   memset(&saddr, 0, sizeof(struct sockaddr_in));
   memset(&iaddr, 0, sizeof(struct in_addr));

   // open a UDP socket
   sock = socket(PF_INET, SOCK_DGRAM, 0);
   if ( sock < 0 )
     perror("Error creating socket"), exit(0);

   saddr.sin_family = PF_INET;
   saddr.sin_port = htons(0); // Use the first free port
   saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind socket to any interface
   status = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));

   if ( status < 0 )
     perror("Error binding socket to interface"), exit(0);

// iaddr.s_addr = INADDR_ANY; // use DEFAULT interface 
  ===> iaddr.s_addr = inet_addr("x.x.x.x"); // ip of the machine on which client is running
   // Set the outgoing interface to DEFAULT
   setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &iaddr,
              sizeof(struct in_addr));

   // Set multicast packet TTL to 3; default TTL is 1
   setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
              sizeof(unsigned char));

   // send multicast traffic to myself too
   status = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
                       &one, sizeof(unsigned char));

   // set destination multicast address
   saddr.sin_family = PF_INET;
   saddr.sin_addr.s_addr = inet_addr("226.0.0.1");
   saddr.sin_port = htons(4096);

   // put some data in buffer
   strcpy(buffer, "Hello world\n");

   socklen = sizeof(struct sockaddr_in);
   // receive packet from socket
   status = sendto(sock, buffer, strlen(buffer), 0,
                     (struct sockaddr *)&saddr, socklen);

   // shutdown socket
   shutdown(sock, 2);
   // close socket
   close(sock);

   return 0;
}

Offline

#4 2009-01-27 02:26 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: setsockopt returns No device Found error in multicast

Please use the code tags when posting large blocks of code!

I'm not sure exactly what the problem is, but I believe you're supposed to use the
newer ip_mreqn struct instead of the old ip_mreq struct for IP_ADD_MEMBERSHIP...
The new one has an interface index, so you can actually specify the real interface
(since IP may not necessarily map one-to-one with interface)...

How are you determining that the setsockopt() failed with ENODEV?  I don't see
anything in that code that actually checks the return value or prints out errno...  Are
you running it through strace, or something?

Have you tried changing the INADDR_ANY in your bind() to use the same IP you
try to use in the IP_ADD_MEMBERSHIP?  Maybe that's the problem: it doesn't like
the fact that the socket is bound to all interfaces, but you're specifying a specific
one to join...  (Of course, I'm not sure why you're not just using INADDR_ANY in
the IP_ADD_MEMBERSHIP as well, anyway...  Seems like that'd be the sanest
approach, in general, rather than hard-coding a specific interface/IP...)

But, I spot a few other issues with that code...  In the client code, you don't want to use
unsigned chars as the args for those setsockopt()'s...  You want plain ints...  Pretty
much all sockopts that take a boolean or simple numeric value of any kind want just
plain ints...  Using anything else is never a wise idea, even if it seems to work...
(You can verify these particular sockopts want ints by checking "man 7 ip"...  I have,
and they do...)  Also, IP_MULTICAST_IF wants a struct ip_mreqn (or old ip_mreq),
not a struct in_addr as you're giving it...

Also, shutdown() will accomplish absolutely nothing of value on a UDP socket...
It's only useful for TCP (or Unix domain stream) sockets, in order to half-close a
socket...  Other than that one specific use, it's completely unnecessary for normal
everyday use...  And, on UDP sockets, it's beyond unnecessary, and actually
totally nonsensical and without a single use at all...

Offline

#5 2009-01-28 07:17 AM

epolluser
Member
Registered: 2008-01-14
Posts: 21

Re: setsockopt returns No device Found error in multicast

sorry for the inconvenience caused.

newer ip_mreqn struct instead of the old ip_mreq struct for IP_ADD_MEMBERSHIP

could you please let me know which header file has to be included for this new structure as it is not defined in netinet/in.h

How are you determining that the setsockopt() failed with ENODEV?

i have done error checking for setsockopt and printing the errno and error string


Have you tried changing the INADDR_ANY in your bind() to use the same IP you try to use in the IP_ADD_MEMBERSHIP? Maybe that's the problem: it doesn't like the fact that the socket is bound to all interfaces, but you're specifying a specific one to join...

yup i did try using the same ip in bind but then bind throws errno 29

why you're not just using INADDR_ANY in the IP_ADD_MEMBERSHIP

I have tried this also here bind is successful but setsockopt again returns errno 19

unsigned chars as the args for those setsockopt()
Also, IP_MULTICAST_IF wants a struct ip_mreqn (or old ip_mreq),
not a struct in_addr as you're giving it

this was in sample code and i have also read this in UNIX Network Programming by W.Richard Stevens that datatype for IP_MULTICAST_TTL & IP_MULTICAST_TTL is u_char
i also referred http://www.linux.org/docs/ldp/howto/Mul … WTO-6.html link where in they have given following examples:
u_char loop;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));

u_char ttl;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

struct in_addr interface_addr;
setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));

I hope i have not missed any point. Please let me know the solution to this problem..

Offline

#6 2009-01-28 02:22 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: setsockopt returns No device Found error in multicast

could you please let me know which header file has to be included for this new structure as it is not defined in netinet/in.h

Yes it is...  Well, it's typically actually defined in some other lower header you should
never directly include, such as <bits/in.h> or <linux/in.h>, however the point is that
all you need to include is <netinet/in.h>, and it will include anything else needed, and
you will have the struct defined...

If you're just looking for documentation on its layout, like I said, read "man 7 ip"...

yup i did try using the same ip in bind but then bind throws errno 29

29??  That's ESPIPE, "Illegal seek"...  Are you sure about that??  If so, sounds like
a spurious errno, and not actually related to the bind() at all...

But, if your bind() to that IP is failing for whatever reason, then chances are you
are simply using an incorrect IP...  Make sure your interface really has that IP you
are using...  Ie: maybe you're trying to use a public IP rather than your private
NAT'd IP, or something similar?  Do "ifconfig" and make sure you see the IP you
are using listed for an interface there...

his was in sample code and i have also read this in UNIX Network Programming by W.Richard Stevens that datatype for IP_MULTICAST_TTL & IP_MULTICAST_TTL is u_char
i also referred http://www.linux.org/docs/ldp/howto/...t-HOWTO-6.html link where in they have given following examples:

Well, what can I tell you: the man page says otherwise...  Read "man 7 ip"...  The
proper arg type is int not uchar, and ip_mreq/ip_mreqn not in_addr...

(However, reading the kernel source, I can see they DO actually support such
incorrect arg types, too...  So, all will probably work ok, if you use them...  But, that
doesn't make them any less wrong...)

Offline

#7 2009-01-29 02:01 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,230

Re: setsockopt returns No device Found error in multicast

No idea why, but printf seems to cause illegal seeks all the time...

Offline

#8 2009-01-29 11:16 AM

epolluser
Member
Registered: 2008-01-14
Posts: 21

Re: setsockopt returns No device Found error in multicast

in interface if i use the respective local ips of the machines where client and server are running the problem gets solved temporarily i.e. datagrams are being sent from server to client successfully.
Still the one query remains why does interface => INADDR_ANY does not work??
setsockopt with IP_ADD_MEMBERSHIP fails with No such Device error errno = 19 and though setsockopt  with IP_MULTICAST_IF  does not throw error sento call returns error Network Unreachable errno = 101.

Offline

#9 2009-01-29 10:22 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,826
Website

Re: setsockopt returns No device Found error in multicast

No idea why, but printf seems to cause illegal seeks all the time...

I think because it always tries to do a seek to EOF prior to writing, which of course
will fail on a tty...

Still the one query remains why does interface => INADDR_ANY does not work??

My guess: none of your configured interfaces support multicasting...  Do "ifconfig":
any interfaces that support multicast will be labeled with a "MULTICAST" flag...  If
that's the case, I couldn't tell you WHY it's not getting set correctly for an ethernet
device...  But, you can manually set it via "ifconfig" or "ip" (and probably setup your
system network init scripts to set it for you at ifup time somehow)...

If it already has the MULTICAST flag, then I don't know why it wouldn't work...

Offline

#10 2009-01-30 12:22 PM

josealf
Guest

Re: setsockopt returns No device Found error in multicast

i had the same problem today.
I 've resolved it by adding a default gateway to my unique local IP address, or adding a multicast route as commented in the following site:
http://www-mice.cs.ucl.ac.uk/multimedia/software/documentation/ipv6.html


route add -net 224.0.0.0 netmask 224.0.0.0 eth0

#11 2009-02-02 10:43 AM

epolluser
Member
Registered: 2008-01-14
Posts: 21

Re: setsockopt returns No device Found error in multicast

thanks a lot. this worked for me.. :)

Offline

#12 2013-03-22 05:25 PM

Merlin
Guest

Re: setsockopt returns No device Found error in multicast

Yeah, I was looking for this for hours! Thanks

#13 2013-07-24 01:35 PM

AwaX
Guest

Re: setsockopt returns No device Found error in multicast

Exactly the same problem, with the same example and your solution worked for me too ! Thanks a lot for your help guys !

#14 2014-04-28 10:56 AM

PangMin
Guest

Re: setsockopt returns No device Found error in multicast

I got this error, and checked the route table, add a default route to the working interface, the error is gone.

#15 2015-08-05 07:33 PM

Abdul Hakkim
Guest

Re: setsockopt returns No device Found error in multicast

Thanks a lot, Its amazingly working...

  • Index
  • » Networking
  • » setsockopt returns No device Found error in multicast

Board footer

Powered by FluxBB