This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: Re: How to add multicast route? - how to add/remove a route
- From: Lambrecht Jürgen <J dot Lambrecht at TELEVIC dot com>
- To: "ecos-discuss at ecos dot sourceware dot org" <ecos-discuss at ecos dot sourceware dot org>
- Cc: "grant dot b dot edwards at gmail dot com" <grant dot b dot edwards at gmail dot com>
- Date: Mon, 6 Jun 2011 13:00:14 +0200
- Subject: Re: [ECOS] Re: How to add multicast route? - how to add/remove a route
- References: <in2gt5$tk$1@dough.gmane.org> <in2hgb$tk$2@dough.gmane.org> <in2sin$5g2$1@dough.gmane.org> <20110401051308.GR17979@lunn.ch> <in4m6s$661$1@dough.gmane.org> <in4p8q$qq2$1@dough.gmane.org>
Hello Grant,
I guess my answer is a bit late, but also for posterity's sake ;-), and
your code worked for me, thanks.
So with the code found here:
http://sourceware.org/ml/ecos-discuss/2011-03/msg00185.html, you can add
an entry in the routing table.
I updated the code, see attach.
Maybe this code could be added to
ecos/packages/net/bsd_tcpip/current/src/ecos/support.c?
However, to add/delete a multicast entry, we do it in another way, from
code we ported from Linux to eCos:
int LeaveMulticast(unsigned long multicastAddr) /* Adress of the multicast group */
{
struct ip_mreq ipMreq; /* Argument structure to setsockopt */
ipMreq.imr_multiaddr.s_addr = htonl(multicastAddr);
/* Unicast interface addr from which to receive the multicast packets */
ipMreq.imr_interface.s_addr = htonl (INADDR_ANY);
/* Set the socket option to leave the multicas group */
if (setsockopt (globalSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
(char *)&ipMreq, sizeof (ipMreq)))
{
...}
}
int JoinMulticast(unsigned long multicastAddr) /* Adress of the multicast group */
{
....idem
/* Set the socket option to join the MULTICAST group */
if (setsockopt (gMDSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&ipMreq, sizeof (ipMreq)) == SOCKET_ERROR)
Those socket defines are in
ecos/packages/net/bsd_tcpip/current/include/netinet/in.h:
And this is the resulting routing table:
Destination Gateway Mask Flags Interface
0.0.0.0 10.0.0.1 0.0.0.0 UG eth0
10.0.0.0 10.0.0.0 255.255.240.0 U eth0
127.0.0.0 127.0.0.1 0.0.0.0 UG lo0
127.0.0.1 127.0.0.1 0.0.0.0 UH lo0
224.0.0.0 224.0.0.0 0.0.0.0 U eth0
(mark, I don't know why the Mask is always 0, this is not correct,
because to delete an entry, you must specify the correct mask! That is
why I added the correct mask myself for eth0 in my notes.)
On 04/01/2011 04:59 PM, Grant Edwards wrote:
> On 2011-04-01, Grant Edwards<grant.b.edwards@gmail.com> wrote:
>
>> I think next I'll try passing either my own address (10.0.0.102, or
>> the local network 10.0.0.0 and see what happens).
> Specifying 10.0.0.0 as the gateway address works. Oddly, the
> resulting routing table looks like this:
>
> Destination Gateway Mask Flags Interface
> 10.0.0.0 10.0.0.0 255.0.0.0 U eth0
> 224.0.0.0 224.0.0.0 240.0.0.0 U eth0
>
> Specifying 10.0.0.0 as the gateway results in the route I wanted with
> 224.0.0.0 as the gateway. Specifying 224.0.0.0 as the gateway fails.
>
> IMO, that's a bug, but whatever...
>
> So for posterity's sake, the initial routing table looked like this:
>
> Destination Gateway Mask Flags Interface
> 10.0.0.0 10.0.0.0 255.0.0.0 U eth0
>
> And the contents of rtentry to add the multicast route were:
>
> rt_dst = 224.0.0.0
> rt_genmask = 240.0.0.0
> rt_gateway = 10.0.0.0
> rt_flags = RTF_UP
>
> It turns out that the rt_dev field is ignored (or at least redundant).
Indeed, that is also what I noticed.
> That's different than the way Linux works: if you specify a device,
> you don't specify a gateway. I'm not sure what the rt_dev field is
> for with the FreeBSD stack...
>
Kind regards,
Jürgen
--
Jürgen Lambrecht
R&D Associate
Tel: +32 (0)51 303045 Fax: +32 (0)51 310670
http://www.televic-rail.com
Televic Rail NV - Leo Bekaertlaan 1 - 8870 Izegem - Belgium
Company number 0825.539.581 - RPR Kortrijk
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2011 Jürgen Lambrecht J.Lambrecht@televic.com
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
/* ----------------------------------------------------------------------------
| Function name : AddMAC
| Description : Add static MAC ENTRY - used in telnet and tty shell
| Parameters : dst: IP address (e.g. "157.55.85.212")
| gateway: MAC address (e.g. "00-aa-00-62-c6-09")
index: interface number (e.g. "1" for eth0)
| Return value : 0 on success, -1 on error
| Notes : From http://sourceware.org/ml/ecos-discuss/2005-09/msg00023.html
| Compile directives: <mandatory, if applicable>
| Author : Sébastien Couret, JL
+ --------------------------------------------------------------------------*/
int AddMAC(const char* dest, const char* gateway, const int index)
{
struct sockaddr_dl gway; // Adresse passerelle
struct sockaddr_in dst; // Réseau/hote cible
char ds[IPSTRING];
struct ecos_rtentry *rt=NULL; // Entrée dans la table de routage
int s=0; // Descripteur de socket
unsigned char cp[MACSTRING]; // Adresse MAC sous forme chaine
memset(&gway,0,sizeof(struct sockaddr_dl));
gway.sdl_family=AF_LINK; // AF_UNSPEC ?
gway.sdl_len=sizeof(struct sockaddr_dl);
gway.sdl_index=index;
gway.sdl_type=IFT_ETHER;
gway.sdl_alen=ETHER_ADDR_LEN;
memcpy(gway.sdl_data,gateway,ETHER_ADDR_LEN);
memset(&dst,0,sizeof(struct sockaddr_in));
dst.sin_family=AF_INET;
dst.sin_port=0;
dst.sin_len=sizeof(struct sockaddr_in);
dst.sin_addr.s_addr=inet_addr(dest);
rt=(struct ecos_rtentry*)malloc(sizeof(struct ecos_rtentry));
if (!rt)
{
debug_printf("Erreur d'allocation d'une route :'%s'",strerror(errno));
return(-1);
}
memset(rt,0,sizeof(struct ecos_rtentry));
rt->rt_flags|=RTF_LLINFO;
rt->rt_flags|=RTF_HOST; // Host entry
memcpy(&(rt->rt_gateway), &gway, sizeof(struct sockaddr));
memcpy(&(rt->rt_dst), &dst, sizeof(struct sockaddr_in));
rt->rt_flags|=RTF_UP; // Route utilisable
rt->rt_flags|=RTF_STATIC; //static arp entry, no refresh needed //RTF_WAS_CLONED;
//rt->rt_use=0;
rt->rt_dev=NULL;
rt->rt_metric=1; // Reseau local
strncpy(ds,inet_ntoa(dst.sin_addr),IPSTRING);
ether_print(gway.sdl_data,cp,MACSTRING); //gateway
debug_printf("Add MAC '%s' for '%s' on eth%d\n",cp,ds,index-1);
s=socket(AF_INET,SOCK_DGRAM,0);
if (s<0)
{
SHOW_RESULT(socket, s);
free(rt);
return(-1);
}
if (ioctl(s,SIOCADDRT,rt)<0)
{
#if JFFS2_TFTP
LOG_RESULT(ioctl, -1);
#else
SHOW_RESULT(ioctl, -1);
#endif
free(rt);
close(s);
return (-1);
}
debug_printf("static ARP entry added\n");
free(rt);
close(s);
return(0);
}
/* ----------------------------------------------------------------------------
| Function name : AddRoute
| Description : Adds a route (use 'route print' on windows to see them,
| or 'ifconfig' in eCos
| Parameters : interface (e.g. "eth0")
| destination (e.g. "10.0.0.0")
| gateway (e.g. "10.0.0.1")
| netmask (e.g. "255.255.0.0")
| Return value : TLV_TRUE is success
| Notes : flags=RTF_UP | RTF_GATEWAY; to add other routes, an
| extra function argument is needed.
| http://sourceware.org/ml/ecos-discuss/2011-03/msg00185.html
| Compile directives: <mandatory, if applicable>
| Author : Grant Edwards, JL
+ --------------------------------------------------------------------------*/
TLV_BOOL AddRoute(const char *interface, const char *destination,
const char *gateway, const char *netmask)
{
struct sockaddr_in addr;
struct ecos_rtentry route;
TLV_BOOL ret;
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s)
{
memset(&route, 0, sizeof route);
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_len = sizeof addr;
addr.sin_addr.s_addr = inet_addr(destination);
memcpy(&route.rt_dst, &addr, sizeof route.rt_dst);
addr.sin_addr.s_addr = inet_addr(gateway);
memcpy(&route.rt_gateway, &addr, sizeof route.rt_gateway);
addr.sin_addr.s_addr = inet_addr(netmask);
memcpy(&route.rt_genmask, &addr, sizeof route.rt_genmask);
route.rt_dev = (char*)interface;
route.rt_flags = RTF_UP | RTF_GATEWAY;
route.rt_metric = 0;
if ((ioctl(s, SIOCADDRT, &route))) {
debug_printf("Error adding route: %s\n", strerror(errno));
ret = TLV_FALSE;
}
else {
debug_printf("Added route %s\n", destination);
ret = TLV_TRUE;
}
close(s);
}
else {
ret = TLV_FALSE;
}
return ret;
}
/* ----------------------------------------------------------------------------
| Function name : DeleteRoute
| Description : Deletes a route (use 'route print' on windows to see them,
| or 'ifconfig' in eCos
| Parameters : interface (e.g. "eth0")
| destination (e.g. "10.0.0.0")
| gateway (e.g. "10.0.0.1")
| netmask (e.g. "255.255.0.0")
| Return value : TLV_TRUE is success
| Notes : flags=RTF_UP; to delete other routes, an extra function
| argument is needed
| Compile directives: <mandatory, if applicable>
| Author : JL
+ --------------------------------------------------------------------------*/
TLV_BOOL DeleteRoute(const char *interface, const char *destination,
const char *gateway, const char *netmask)
{
struct sockaddr_in addr;
struct ecos_rtentry route;
TLV_BOOL ret;
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s)
{
memset(&route, 0, sizeof route);
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_len = sizeof addr;
addr.sin_addr.s_addr = inet_addr(destination);
memcpy(&route.rt_dst, &addr, sizeof route.rt_dst);
addr.sin_addr.s_addr = inet_addr(gateway);
memcpy(&route.rt_gateway, &addr, sizeof route.rt_gateway);
addr.sin_addr.s_addr = inet_addr(netmask);
memcpy(&route.rt_genmask, &addr, sizeof route.rt_genmask);
route.rt_dev = (char*)interface;
route.rt_flags = RTF_UP;
route.rt_metric = 0;
if ((ioctl(s, SIOCDELRT, &route))) {
debug_printf("Error deleting route: %s\n", strerror(errno));
ret = TLV_FALSE;
}
else {
debug_printf("Deleted route %s\n", destination);
ret = TLV_TRUE;
}
close(s);
}
else {
ret = TLV_FALSE;
}
return ret;
}
/* ------------------------------------------------------------------------- +
| END
+ ------------------------------------------------------------------------- */
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss