This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Re: How to add multicast route? - how to add/remove a route


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]