From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Tue, 01 Mar 2016 23:24:55 +0100 From: "Mariusz Janiak" Message-ID: <56d616b706ffa3.50702648@wp.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Subject: Re: [Xenomai] Odp: Re: RTnet -- receive broadcast frame at the local machine List-Id: Discussions about the Xenomai project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gilles Chanteperdrix Cc: Xenomai Dnia Wtorek, 1 Marca 2016 23:05 Gilles Chanteperdrix napisa=B3(a)=20 > On Tue, Mar 01, 2016 at 10:59:03PM +0100, Mariusz Janiak wrote: > > Dnia Wtorek, 1 Marca 2016 07:57 Gilles Chanteperdrix napisa=B3(a)=20 > > > On Mon, Feb 29, 2016 at 10:57:53PM +0100, Mariusz Janiak wrote: > > > > Dnia Poniedzia=B3ek, 29 Lutego 2016 22:08 Gilles Chanteperdrix napisa=B3(a)=20 > > > > > On Mon, Feb 29, 2016 at 09:58:25PM +0100, Mariusz Janiak wrote: > > > > > > Dnia Poniedzia=B3ek, 29 Lutego 2016 21:29 Gilles Chante7erdrix = napisa=B3(a)=20 > > > > > > > On Mon, Feb 29, 2016 at 09:24:11PM +0100, Mariusz Janiak wrot= e: > > > > > > > > Dear Xenomai users, > > > > > > > >=20 > > > > > > > > Since RTnet has been integrated with Xenomai I address this= question to you. The question is, how to receive a broadcast frame at the = local machine without using the localhost? The issue is following, we have = two process with separate rtsockets at the single machine (of course we hav= e different machines in the network but this is not a case). One process se= nd a broadcast UDP frame to the specified UDP port -- we have one rteth dev= ice on the machine. The second process listen on=20 > > that=20 > > > > port=20 > > > > > > > > (receivefrom) and does not receive the broadcast frame sent= by first process. I have found the following thread on the RTnet mailing l= ist=20 > > > > > > > >=20 > > > > > > > > https://sourceforge.net/p/rtnet/mailman/message/6787561/ > > > > > > > >=20 > > > > > > > > Could you please point me the place which should be hacked = to duplicate outgoing packets if there are multiple > > > > > > > > matching routes? > > > > > > >=20 > > > > > > > I ma not sure I understand what you are looking for, but to r= eceive > > > > > > > on a host the frames sent by that host, you need to enable an= d load > > > > > > > the loopback module. When you do that, no hack should be need= ed. > > > > > > >=20 > > > > > > > --=20 > > > > > > > Gilles. > > > > > > > https://click-hack.org > > > > > >=20 > > > > > > Hi Gilles, > > > > > >=20 > > > > > > I am pretty sure that loopback module has been loaded, this is = standard RTnet configuration that has not been changed by me. Beside that, = there is rtlo (127.0.0.1) device which is created when RT_LOOPBACK=3D"yes" = in rtnet.conf.=20 > > > > > >=20 > > > > > > Below you will find simple testcase. Compile this using Xenomai= posix skin.=20 > > > > > >=20 > > > > > > 1) receiver.c > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #define DEF_REC_PORT 1883 > > > > > >=20 > > > > > > int sock; > > > > > > struct sockaddr_in rec_addr; > > > > > >=20 > > > > > > int main() > > > > > > { > > > > > > int enable =3D 1; > > > > > > int buffer[100]; > > > > > > socklen_t len =3D sizeof(rec_addr); > > > > > >=20 > > > > > > mlockall(MCL_CURRENT|MCL_FUTURE); > > > > >=20 > > > > > 1-> > > > > >=20 > > > > > >=20 > > > > > > sock =3D socket(AF_INET, SOCK_DGRAM, 0); > > > > >=20 > > > > > 2-> > > > > >=20 > > > > > > setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(en= able)); > > > > >=20 > > > > > 3-> > > > > >=20 > > > > > >=20 > > > > > > memset(&rec_addr, 0, sizeof(struct sockaddr_in)); > > > > > > rec_addr.sin_family =3D AF_INET; > > > > > > rec_addr.sin_port =3D htons(DEF_REC_PORT); > > > > > > rec_addr.sin_addr.s_addr =3D INADDR_ANY; > > > > > > bind(sock, (struct sockaddr *) &rec_addr, sizeof(struct > > > > > > sockaddr_in)); > > > > >=20 > > > > > 4-> > > > > >=20 > > > > > >=20 > > > > > > while (1) { > > > > > > memset(buffer, 0, 100); > > > > > > recvfrom(sock, buffer, 100, 0, &rec_addr, &len); > > > > >=20 > > > > > 5-> > > > > >=20 > > > > > > printf("%s\n", buffer); > > > > > > } > > > > > > close(sock); > > > > > > return 0; > > > > > > } > > > > > >=20 > > > > > >=20 > > > > > > 2. sender.c > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #include > > > > > > #define DEF_SND_PORT 1883 > > > > > > #define DEF_SND_IP "10.0.0.255" > > > > > >=20 > > > > > > int sock; > > > > > > struct sockaddr_in snd_addr; > > > > > > int ret, size; > > > > > >=20 > > > > > > int main() > > > > > > { > > > > > > int enable =3D 1; > > > > > > struct in_addr snd_ip; > > > > > > char buffer[] =3D "Hello"; > > > > > > socklen_t len =3D sizeof(snd_addr); > > > > > >=20 > > > > > > mlockall(MCL_CURRENT|MCL_FUTURE); > > > > >=20 > > > > > 6-> > > > > >=20 > > > > > >=20 > > > > > > inet_aton(DEF_SND_IP, &snd_ip); > > > > >=20 > > > > > 7-> > > > > >=20 > > > > > > sock =3D socket(AF_INET, SOCK_DGRAM, 0); > > > > >=20 > > > > > 8-> > > > > >=20 > > > > > > setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &enable, > > > > > > sizeof(enable)); > > > > >=20 > > > > > 9-> > > > > >=20 > > > > > >=20 > > > > > > memset(&snd_addr, 0, sizeof(struct sockaddr_in)); > > > > > > snd_addr.sin_family =3D AF_INET; > > > > > > snd_addr.sin_port =3D htons(DEF_SND_PORT); > > > > > > snd_addr.sin_addr =3D snd_ip; > > > > > >=20 > > > > > > while (1) { > > > > > > ret =3D sendto(sock, buffer, 6, 0 , &snd_addr, len); > > > > >=20 > > > > > 10-> > > > > >=20 > > > > > So, that is 10 function calls without checking the return value. > > > > > Please check the function return values. > > > > >=20 > > > > > --=20 > > > > > Gilles. > > > > > https://click-hack.org > > > >=20 > > > > You are right the test case has not been perfect. The answer to the= first question, sending to unicast cause that receiver get frames. Regardi= ng the return values of the syscalls when broadcast > > > >=20 > > > > 1 -> 0 > > > > 2 -> 896 > > > > 3 -> -1 > > > > 4 -> 0 > > > >=20 > > > > Five is not printed because of waiting on recvfrom > > > >=20 > > > > 6 -> 0 > > > > 7 -> 1 > > > > 8 -> 897 > > > > 9 -> -1 > > > > 10 -> -1 > > > > 10 -> -1 > > > > 10 -> -1 > > > > 10 -> -1 > > > > 10 -> -1 > > >=20 > > > So, finally, the problem is that SO_BROADCAST is not implemented for > > > RTnet sockets, and that RTnet sendto does not work for a broadcast > > > address? > > >=20 > > > --=20 > > > Gilles. > > > https://click-hack.org > >=20 > > It does work, but when you receive on remote host, and it doesn't when = receive on the same host. According to this post on the RTnet forum=20 > >=20 > > https://sourceforge.net/p/rtnet/mailman/message/26686897/ > >=20 > > the RT-UDP sockets have SO_BROADCAST automatically enabled. >=20 > From what I understand from this post, it is not easy to fix, as it > requires duplicating packets. So, patch welcome. Ok, we went back to the original question, could someone point the place th= at has to be modified. I have played a little bit with the RTnet stack rece= ntly, but this task require far better understanding of the stack. Maybe so= meone more advanced can give some guidelines.=20 > The thing that I do not understand though, is that according to what > you said, "sendto" fails, what is the value of errno when it fails. > Maybe you do not know it, because you do not seem to be used to > checking for errors, but when a unix call fails, it returns -1 and > sets errno, the interesting information is errno. My fault, I forgot to add broadcast address that is used in example. Anyway= , changing to default broadcast 10.255.255.255 or adding 10.0.0.255 with rt= route give the same result=20 6 -> 0 7 -> 1 8 -> 896 9 -> -1 10 -> 6 10 -> 6 10 -> 6 10 -> 6 Mariusz > --=20 > Gilles. > https://click-hack.org