original files of m241
This commit is contained in:
@@ -0,0 +1,902 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp.c,v $ $Revision: 1.30.10.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp.c,v $
|
||||
* $Author: jren $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_ipd.h>
|
||||
#include <ipcom_os.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#include <ipnet_routesock.h>
|
||||
|
||||
#include "ipmcp.h"
|
||||
#include "ipmcp_h.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IPCOM_PROCESS(ipmcp_daemon);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
Ipmcp_data_t ipmcp;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_if_destroy
|
||||
*===========================================================================
|
||||
* Description: Frees all resources held by the interface structure.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_if_destroy(Ipmcp_netif_t *netif)
|
||||
{
|
||||
if (netif == IP_NULL)
|
||||
return;
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ipmcp_igmp_if_destroy(netif);
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ipmcp_mld_if_destroy(netif);
|
||||
#endif
|
||||
|
||||
ipcom_list_remove(&netif->list);
|
||||
ipcom_free(netif);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_if_create
|
||||
*===========================================================================
|
||||
* Description: Create interface descriptors for IPMCP
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_if_create(Ip_u32 ifindex)
|
||||
{
|
||||
Ipmcp_netif_t *netif;
|
||||
int ret;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
char *downstream_if;
|
||||
char *p = IP_NULL;
|
||||
char *sep = ", ";
|
||||
char *ds;
|
||||
|
||||
netif = ipmcp_if_find(ifindex);
|
||||
if (netif)
|
||||
/* Duplicate */
|
||||
return -1;
|
||||
|
||||
if (ipcom_if_indextoname(ifindex, ifname) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipmcp_if_create: could not get the name of the interface with index %d", ifindex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ds = ipcom_strdup(ipmcp.config.downstream_ifs);
|
||||
if (ds == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipmcp_if_create: failed to duplicate string", ifindex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (downstream_if = ipcom_strtok_r(ds, sep, &p);
|
||||
downstream_if != IP_NULL;
|
||||
downstream_if = ipcom_strtok_r(IP_NULL, sep, &p))
|
||||
{
|
||||
if (ipcom_strcmp(ifname, downstream_if) == 0)
|
||||
break;
|
||||
}
|
||||
ipcom_free(ds);
|
||||
|
||||
if (downstream_if == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(DEBUG, "ipmcp_if_create: interface %s is not a downstream interface, ignoring",
|
||||
ifname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
netif = ipcom_calloc(1, sizeof(Ipmcp_netif_t));
|
||||
if (netif == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipmcp_if_create: failed to allocate memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
netif->ifindex = ifindex;
|
||||
ipcom_strcpy(netif->ifname, ifname);
|
||||
ipcom_list_insert_last(&ipmcp.downstream_ifs_head, &netif->list);
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ret = ipmcp_igmp_if_create(netif);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ret = ipmcp_mld_if_create(netif);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
ipmcp_if_destroy(netif);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_add_downstream_ifs
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_add_downstream_ifs(void)
|
||||
{
|
||||
struct Ip_if_nameindex *ifrs, *i;
|
||||
struct Ip_ifreq ifreq;
|
||||
int ret = -1;
|
||||
|
||||
ifrs = ipcom_if_nameindex();
|
||||
|
||||
for (i = ifrs; i && (i->if_name != IP_NULL); i++)
|
||||
{
|
||||
/* coverity[fixed_size_dest] : FALSE */
|
||||
ipcom_strcpy(ifreq.ifr_name, i->if_name);
|
||||
#ifdef IP_PORT_LAS
|
||||
if (ipcom_socketioctl(ipmcp.cfg_fd, IP_SIOCGIFFLAGS, (char*)&ifreq) < 0)
|
||||
#else
|
||||
if (ipcom_socketioctl(ipmcp.ipd_fd, IP_SIOCGIFFLAGS, (char*)&ifreq) < 0)
|
||||
#endif
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipcom_ioctl(SIOCGIFFLAGS) failed, errno = %d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Skip loopback */
|
||||
if (IP_BIT_ISSET(ifreq.ifr_ifru.ifru_flags, IP_IFF_LOOPBACK))
|
||||
continue;
|
||||
|
||||
/* Skip if not multicast capable */
|
||||
if (IP_BIT_ISFALSE(ifreq.ifr_ifru.ifru_flags, IP_IFF_MULTICAST))
|
||||
continue;
|
||||
|
||||
/* Skip if DOWN */
|
||||
if (IP_BIT_ISFALSE(ifreq.ifr_ifru.ifru_flags, IP_IFF_UP))
|
||||
continue;
|
||||
|
||||
if (ipmcp_if_create(i->if_index) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
ipcom_if_freenameindex(ifrs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_upstream_if_add
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_upstream_if_add(void)
|
||||
{
|
||||
struct Ip_ifreq ifreq;
|
||||
Ip_size_t namsiz = sizeof(ifreq.ifr_name);
|
||||
int ret;
|
||||
|
||||
if (ipcom_sysvar_get("ipmcp.UpstreamIf", ifreq.ifr_name, &namsiz) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "missing 'ipmcp.UpstreamIf'");
|
||||
IP_PANIC2();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ipcom_strcpy(ipmcp.upstream_if.ifname, ifreq.ifr_name);
|
||||
|
||||
ipmcp.upstream_if.ifindex = ipcom_if_nametoindex(ifreq.ifr_name);
|
||||
if (ipmcp.upstream_if.ifindex == 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "upstream interface %s is not attached to the stack", ifreq.ifr_name);
|
||||
IP_PANIC2();
|
||||
return -1;
|
||||
}
|
||||
#ifdef IP_PORT_LAS
|
||||
if (ipcom_socketioctl(ipmcp.cfg_fd, IP_SIOCGIFFLAGS, (char*)&ifreq) < 0)
|
||||
#else
|
||||
if (ipcom_socketioctl(ipmcp.ipd_fd, IP_SIOCGIFFLAGS, (char*)&ifreq) < 0)
|
||||
#endif
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipcom_ioctl(SIOCGIFFLAGS) failed: %s", ipcom_strerror(ipcom_errno));
|
||||
IP_PANIC();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IP_BIT_ISSET(ifreq.ifr_ifru.ifru_flags, IP_IFF_LOOPBACK)
|
||||
|| IP_BIT_ISFALSE(ifreq.ifr_ifru.ifru_flags, IP_IFF_MULTICAST))
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s cannot be used as uplink interface, must not be loopback and must be multicast capable",
|
||||
ifreq.ifr_name);
|
||||
IP_PANIC2();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IP_BIT_ISSET(ifreq.ifr_ifru.ifru_flags, IP_IFF_UP))
|
||||
ipmcp.state = IPMCP_STATE_RUNNING;
|
||||
else
|
||||
{
|
||||
IPCOM_LOG1(NOTICE,
|
||||
"%s was found, but is currently not UP, enter WAITING state",
|
||||
ifreq.ifr_name);
|
||||
ipmcp.state = IPMCP_STATE_WAITING;
|
||||
}
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ret = ipmcp_igmp_upstream_if_create(&ipmcp.upstream_if);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ret = ipmcp_mld_upstream_if_create(&ipmcp.upstream_if);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_upstream_if_destroy
|
||||
*===========================================================================
|
||||
* Description: Removes the upstream interface.
|
||||
* Parameters:
|
||||
* Returns: 0 = success, <0 = error.
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_upstream_if_destroy(void)
|
||||
{
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ipmcp_igmp_upstream_if_destroy(&ipmcp.upstream_if);
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ipmcp_mld_upstream_if_destroy(&ipmcp.upstream_if);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_apply_configuration
|
||||
*===========================================================================
|
||||
* Description: Setup the system according to the configuration.
|
||||
* Parameters:
|
||||
* Returns: 0 = success, <0 = error.
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_setup_configuration(void)
|
||||
{
|
||||
Ipmcp_conf_t *conf = &ipmcp.config;
|
||||
|
||||
if (ipmcp_upstream_if_add() < 0)
|
||||
return -1;
|
||||
|
||||
/* Read sysvar configuration. */
|
||||
conf->robustness_variable = (Ip_u32)ipcom_sysvar_get_as_int("ipmcp.RobustnessVariable", 2);
|
||||
if (conf->robustness_variable == 0 || conf->robustness_variable == 0xffffffff)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "invalid 'ipmcp.RobustnessVariable'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
conf->query_interval = (Ip_u32)ipcom_sysvar_get_as_int("ipmcp.QueryInterval", 125);
|
||||
if (conf->query_interval > 0xffffffff / 1000)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "No support for query intervals > %u 'ipmcp.QueryInterval'", 0xffffffff / 1000);
|
||||
return -1;
|
||||
}
|
||||
conf->query_interval *= 1000; /* milliseconds */
|
||||
|
||||
conf->query_response_interval =
|
||||
(Ip_u16)ipcom_sysvar_get_as_int("ipmcp.QueryResponseInterval", 10000);
|
||||
conf->last_member_query_interval =
|
||||
(Ip_u32)ipcom_sysvar_get_as_int("ipmcp.LastMemberQueryInterval", 1000);
|
||||
conf->last_member_query_count =
|
||||
(Ip_u32)ipcom_sysvar_get_as_int("ipmcp.LastMemberQueryCount", conf->robustness_variable);
|
||||
|
||||
/* Calculate some parameters */
|
||||
conf->startup_query_interval =
|
||||
(Ip_u32)ipcom_sysvar_get_as_int("ipmcp.StartupQueryInterval", 0) * 1000;
|
||||
if (conf->startup_query_interval == 0)
|
||||
conf->startup_query_interval = conf->query_interval / 4;
|
||||
conf->startup_query_count = conf->robustness_variable;
|
||||
|
||||
ipmcp.config.downstream_ifs = ipcom_sysvar_get("ipmcp.DownstreamIfs", IP_NULL, IP_NULL);
|
||||
if (ipmcp.config.downstream_ifs == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "missing 'ipmcp.DownstreamIfs'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ipmcp_add_downstream_ifs();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_teardown_configuration
|
||||
*===========================================================================
|
||||
* Description: Frees all resouces that is tied to the current configuration.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_teardown_configuration(void)
|
||||
{
|
||||
Ipmcp_netif_t *i;
|
||||
|
||||
ipmcp.state = IPMCP_STATE_HALTED;
|
||||
|
||||
for (i = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
i != IP_NULL;
|
||||
i = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head))
|
||||
{
|
||||
ipmcp_if_destroy(i);
|
||||
}
|
||||
|
||||
ipmcp_upstream_if_destroy();
|
||||
ipcom_free(ipmcp.config.downstream_ifs);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_init
|
||||
*===========================================================================
|
||||
* Description: Initializes the multicast proxy.
|
||||
* Parameters:
|
||||
* Returns: 0 = success, <0 = error.
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_init(void)
|
||||
{
|
||||
int ret;
|
||||
Ip_err err = IPCOM_ERR_FAILED;;
|
||||
|
||||
ipcom_list_init(&ipmcp.downstream_ifs_head);
|
||||
|
||||
ipmcp.tmo_head = ipcom_tmo2_new();
|
||||
if (ipmcp.tmo_head == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to create timeout head");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ipmcp.rt_fd = ipcom_socket(IP_AF_ROUTE, IP_SOCK_RAW, 0);
|
||||
if (ipmcp.rt_fd == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipcom_socket(ROUTE,RAW) failed: %s", ipcom_strerror(ipcom_errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef IP_PORT_LAS
|
||||
ipmcp.cfg_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
|
||||
if (ipmcp.cfg_fd == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipcom_socket(INET,DGRAM) failed: %s", ipcom_strerror(ipcom_errno));
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
if (0 > (ret = ipmcp_igmp_init()))
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#ifdef IPMCP_USE_MLD
|
||||
if (0 > (ret = ipmcp_mld_init()))
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
err = IPCOM_SUCCESS;;
|
||||
done:
|
||||
if (ipcom_ipd_init(IPMCP_IPD_NAME, err, &ipmcp.ipd_fd) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "Failed to initialize IPD: %s", ipcom_strerror(ipcom_errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_exit
|
||||
*===========================================================================
|
||||
* Description: Frees all resources held by the daemon.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_exit(void)
|
||||
{
|
||||
(void)ipcom_ipd_exit("ipmcp", ipmcp.ipd_fd);
|
||||
(void)ipcom_socketclose(ipmcp.rt_fd);
|
||||
#ifdef IP_PORT_LAS
|
||||
(void)ipcom_socketclose(ipmcp.cfg_fd);
|
||||
#endif
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ipmcp_igmp_exit();
|
||||
#endif
|
||||
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ipmcp_mld_exit();
|
||||
#endif
|
||||
|
||||
ipcom_tmo2_delete(ipmcp.tmo_head);
|
||||
ipmcp_is_enabled = IP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_ipd_input
|
||||
*===========================================================================
|
||||
* Description: Processes IPD messages,
|
||||
* Parameters: fd - The IPD socket
|
||||
* done - Will be set to true if the daemon should shutdown.
|
||||
* Returns: 0 = Daemon will continue and process other messages.
|
||||
* 1 = The daemon must reconfigure itsef.
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_ipd_input(int fd, Ip_bool *done)
|
||||
{
|
||||
switch (ipcom_ipd_input(fd))
|
||||
{
|
||||
case IPCOM_IPD_EVENT_RECONFIGURE:
|
||||
IPCOM_LOG0(INFO, "received IPD reconfigure message");
|
||||
*done = IP_FALSE;
|
||||
return 1;
|
||||
|
||||
case IPCOM_IPD_EVENT_KILL:
|
||||
IPCOM_LOG0(INFO, "received IPD kill message");
|
||||
*done = IP_TRUE;
|
||||
return 1;
|
||||
|
||||
case IPMCP_IPD_EVENT_WAIT_FOR_SHELL_CMD:
|
||||
/* Notify the shell command that the MCP daemon now waiting
|
||||
here */
|
||||
(void)ipcom_sem_post(ipmcp.cmd_sem);
|
||||
|
||||
/* This will block this task until the shell command has
|
||||
finished reading the state of the MCP daemon */
|
||||
(void)ipcom_mutex_lock(ipmcp.daemon_mutex);
|
||||
(void)ipcom_mutex_unlock(ipmcp.daemon_mutex);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_route_input
|
||||
*===========================================================================
|
||||
* Description: Processes route socket messages.
|
||||
* Parameters: fd - The route socket
|
||||
* Returns: 0 = success
|
||||
* <0 = error
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipmcp_route_input(int fd)
|
||||
{
|
||||
Ipmcp_netif_t *netif;
|
||||
int length;
|
||||
union rtmsg_union
|
||||
{
|
||||
struct Ipnet_rt_msghdr rtmsg;
|
||||
struct Ipnet_if_msghdr ifmsg;
|
||||
struct Ipnet_ifa_msghdr ifamsg;
|
||||
} buf;
|
||||
|
||||
/* Read routing message headers only (truncated read). */
|
||||
length = ipcom_recv(fd, &buf, sizeof(buf), 0);
|
||||
if (length == IP_SOCKERR)
|
||||
{
|
||||
IP_PANIC2();
|
||||
IPCOM_LOG1(ERR, "ipmcp_route_input: ipcom_recv() failed, errno = %d", ipcom_errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length < (int) sizeof(struct Ipnet_rs_msghdr))
|
||||
{
|
||||
IP_PANIC2();
|
||||
IPCOM_LOG2(ERR, "ipmcp_route_input: ipcom_recv() failed, truncated rtsock message %ld/%d", length,
|
||||
(int)sizeof(struct Ipnet_rs_msghdr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (buf.rtmsg.rtm_type)
|
||||
{
|
||||
case IPNET_RTM_DELADDR:
|
||||
case IPNET_RTM_NEWADDR:
|
||||
netif = ipmcp_if_find(buf.ifamsg.ifam_index);
|
||||
if (netif)
|
||||
{
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ipmcp_igmp_addr_change(netif, buf.rtmsg.rtm_type == IPNET_RTM_NEWADDR);
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ipmcp_mld_addr_change(netif, buf.rtmsg.rtm_type == IPNET_RTM_NEWADDR);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case IPNET_RTM_IFINFO:
|
||||
if (IP_BIT_ISSET(buf.ifmsg.ifm_flags, IP_IFF_UP))
|
||||
(void) ipmcp_if_create(buf.ifmsg.ifm_index);
|
||||
else
|
||||
ipmcp_if_destroy(ipmcp_if_find(buf.ifmsg.ifm_index));
|
||||
break;
|
||||
|
||||
default:
|
||||
/* ignore all other routing messages. */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_daemon
|
||||
*===========================================================================
|
||||
* Description: Multicast proxy daemon.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IPCOM_PROCESS(ipmcp_daemon)
|
||||
{
|
||||
int max_fd;
|
||||
int num;
|
||||
int ret = 0;
|
||||
Ip_fd_set read_set;
|
||||
int retries;
|
||||
Ip_bool done = IP_FALSE;
|
||||
|
||||
ipcom_proc_init();
|
||||
|
||||
IPCOM_LOG0(INFO, "Multicast proxy daemon starting");
|
||||
|
||||
ret = ipmcp_init();
|
||||
if (0 > ret)
|
||||
done = IP_TRUE;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
ret = ipmcp_setup_configuration();
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
ipmcp_is_enabled = IP_TRUE;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
IP_FD_ZERO(&read_set);
|
||||
IP_FD_SET(ipmcp.ipd_fd, &read_set);
|
||||
IP_FD_SET(ipmcp.rt_fd, &read_set);
|
||||
max_fd = IP_MAX(ipmcp.rt_fd, ipmcp.ipd_fd);
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
IP_FD_SET(ipmcp.igmp.fd, &read_set);
|
||||
max_fd = IP_MAX(ipmcp.igmp.fd, max_fd);
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
IP_FD_SET(ipmcp.mld.mld_fd, &read_set);
|
||||
max_fd = IP_MAX(ipmcp.mld.mld_fd, max_fd);
|
||||
IP_FD_SET(ipmcp.mld.mrt_fd, &read_set);
|
||||
max_fd = IP_MAX(ipmcp.mld.mrt_fd, max_fd);
|
||||
#endif
|
||||
|
||||
done = IP_TRUE;
|
||||
|
||||
for (retries = 0, num = 0; num <= 0 && retries < 3; retries++)
|
||||
{
|
||||
num = ipcom_tmo2_select(ipmcp.tmo_head, max_fd + 1, &read_set, IP_NULL, IP_NULL, IP_NULL);
|
||||
if (num < 0)
|
||||
IPCOM_LOG1(WARNING, "socket select returned %s", ipcom_strerror(ipcom_errno));
|
||||
}
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "socket select returned %s, shutting down", ipcom_strerror(ipcom_errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (IP_FD_ISSET(ipmcp.ipd_fd, &read_set) && ipmcp_ipd_input(ipmcp.ipd_fd, &done) != 0)
|
||||
break;
|
||||
|
||||
if (IP_FD_ISSET(ipmcp.rt_fd, &read_set) && ipmcp_route_input(ipmcp.rt_fd) < 0)
|
||||
break;
|
||||
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
if (IP_FD_ISSET(ipmcp.igmp.fd, &read_set)
|
||||
&& ipmcp_igmp_input(ipmcp.igmp.fd) < 0)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef IPMCP_USE_MLD
|
||||
if (IP_FD_ISSET(ipmcp.mld.mld_fd, &read_set)
|
||||
&& ipmcp_mld_input(ipmcp.mld.mld_fd) < 0)
|
||||
break;
|
||||
|
||||
if (IP_FD_ISSET(ipmcp.mld.mrt_fd, &read_set)
|
||||
&& ipmcp_mld_mroute_input(ipmcp.mld.mrt_fd) < 0)
|
||||
break;
|
||||
#endif
|
||||
|
||||
done = IP_FALSE;
|
||||
}
|
||||
|
||||
ipmcp_teardown_configuration();
|
||||
}
|
||||
|
||||
ipmcp_exit();
|
||||
|
||||
IPCOM_LOG0(INFO, "Multicast proxy daemon ending");
|
||||
ipcom_proc_exit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_if_find
|
||||
*===========================================================================
|
||||
* Description: Finds the interface that matches the index.
|
||||
* Parameters:
|
||||
* Returns: The interface structure or IP_NULL if it does not exists.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipmcp_netif_t *
|
||||
ipmcp_if_find(Ip_u32 ifindex)
|
||||
{
|
||||
Ipmcp_netif_t *i;
|
||||
|
||||
for (i = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
i != IP_NULL;
|
||||
i = IPCOM_LIST_NEXT(&i->list))
|
||||
{
|
||||
if (ifindex == i->ifindex)
|
||||
return i;
|
||||
}
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_route_init_addrs
|
||||
*===========================================================================
|
||||
* Description: Sets the address pointer to point to the correct entry
|
||||
* in the 'rt' buffer.
|
||||
* Parameters: msg - The first socket address in the route socket message.
|
||||
* addrs - The IPNET_RTA_xxx from the message.
|
||||
* sas - Will contain the route pointer.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipmcp_route_init_addrs(void *msg, Ip_u32 addrs, struct Ip_sockaddr **sas)
|
||||
{
|
||||
int i;
|
||||
Ip_size_t offset = 0;
|
||||
|
||||
for (i = 0; i < IPNET_RTAX_MAX; i++)
|
||||
{
|
||||
if (IP_BIT_ISSET(addrs, 1 << i))
|
||||
{
|
||||
sas[i] = (struct Ip_sockaddr *) &((Ip_u8 *) msg)[offset];
|
||||
offset += IPCOM_SA_LEN_GET(sas[i]);
|
||||
}
|
||||
else
|
||||
sas[i] = IP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_create
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipmcp_create(void)
|
||||
{
|
||||
Ip_err ret;
|
||||
|
||||
ipcom_memset(&ipmcp, 0, sizeof(Ipmcp_data_t));
|
||||
|
||||
if ((ret = ipcom_mutex_create(&ipmcp.daemon_mutex)) != IPCOM_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((ret = ipcom_sem_create(&ipmcp.cmd_sem, 0)) != IPCOM_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_start
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipmcp_start(void)
|
||||
{
|
||||
Ip_err ret;
|
||||
Ipcom_proc_attr attr;
|
||||
|
||||
ipcom_proc_attr_init(&attr);
|
||||
|
||||
ipmcp.ipd_fd = IP_INVALID_SOCKET;
|
||||
ipmcp.rt_fd = IP_INVALID_SOCKET;
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
ipmcp.igmp.fd = IP_INVALID_SOCKET;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
ipmcp.mld.mld_fd = IP_INVALID_SOCKET;
|
||||
ipmcp.mld.mrt_fd = IP_INVALID_SOCKET;
|
||||
#endif
|
||||
|
||||
ret = ipcom_proc_acreate("ipmcp", ipmcp_daemon, &attr, IP_NULL);
|
||||
ip_assert(ret == IPCOM_SUCCESS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_version
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC const char *
|
||||
ipmcp_version(void)
|
||||
{
|
||||
return "@(#) IPMCP $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,675 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp_cmd.c,v $ $Revision: 1.16 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp_cmd.c,v $
|
||||
* $Author: jhorteli $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
* Shows statistics about multicast interfaces and multicast routes.
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_getopt.h>
|
||||
#include <ipcom_ipd.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_type.h>
|
||||
#ifdef IPMCP_USE_MLD
|
||||
#include <ipcom_sock6.h>
|
||||
#endif
|
||||
|
||||
#include "ipmcp_mcast.h"
|
||||
#include "ipmcp_h.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPMCP_CMD_SHOW_IF_STAT 1
|
||||
#define IPMCP_CMD_SHOW_RT_STAT 2
|
||||
#define IPMCP_CMD_SHOW_JG_STAT 3
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_PUBLIC int ipmcp_cmd(int argc, char **argv);
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_link_state_to_str
|
||||
*===========================================================================
|
||||
* Description: Returns a string representation of the link state.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC IP_CONST char *
|
||||
ipmcp_cmd_link_state_to_str(int state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case IPMCP_LINK_STATE_INACTIVE:
|
||||
return "INACTIVE";
|
||||
case IPMCP_LINK_STATE_NON_QUERIER:
|
||||
return "NON-QUERIER";
|
||||
case IPMCP_LINK_STATE_QUERIER:
|
||||
return "QUERIER";
|
||||
default:
|
||||
IP_PANIC();
|
||||
return "unknown state";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_maddr_source_addr_cb
|
||||
*===========================================================================
|
||||
* Description: Prints one multicast source address.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_maddr_source_addr_cb(Ipmcp_saddr_t *saddr, const char *prefix)
|
||||
{
|
||||
char addrstr[IPMCP_ADDRSTRLEN];
|
||||
|
||||
ipcom_printf("%s%-20s %u" IP_LF, prefix,
|
||||
ipcom_inet_ntop(saddr->maddr->domain,
|
||||
saddr->ops->get_addr(saddr),
|
||||
addrstr,
|
||||
sizeof(addrstr)),
|
||||
ipcom_tmo2_get(&saddr->timer) / 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_joined_groups_cb
|
||||
*===========================================================================
|
||||
* Description: Prints one joined multicast group.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_joined_groups_cb(Ipmcp_maddr_t *maddr, void *unused)
|
||||
{
|
||||
char addrstr[IPMCP_ADDRSTRLEN];
|
||||
char *set_indent = "\t\t";
|
||||
|
||||
(void) unused;
|
||||
ipcom_printf("\t%s%-19s %s %u" IP_LF,
|
||||
maddr->domain == IP_AF_INET6 ? " " : "",
|
||||
ipcom_inet_ntop(maddr->domain, maddr->ops->get_addr(maddr), addrstr, sizeof(addrstr)),
|
||||
maddr->mode_is_include ? "INCLUDE" : "EXCLUDE",
|
||||
ipcom_tmo2_get(&maddr->group_timer) / 1000);
|
||||
ipcom_printf("%sInclude set:" IP_LF, set_indent);
|
||||
ipcom_hash_for_each(maddr->include_set,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_maddr_source_addr_cb,
|
||||
set_indent);
|
||||
|
||||
ipcom_printf("%sExclude set:" IP_LF, set_indent);
|
||||
ipcom_hash_for_each(maddr->exclude_set,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_maddr_source_addr_cb,
|
||||
set_indent);
|
||||
}
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet_ifs
|
||||
*===========================================================================
|
||||
* Description: Shows all the IPv4 multicast intefaces.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet_ifs(void)
|
||||
{
|
||||
struct Ip_sioc_vif_req vif_req;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
vif_req.vifi = ipmcp.upstream_if.igmp.vif_index;
|
||||
if (ipcom_socketioctl(ipmcp.igmp.fd, IP_SIOCGETVIFCNT, &vif_req) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETVIFCNT failed for upstream interface: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("Upstream interface IPv4 statistics"IP_LF);
|
||||
ipcom_printf("\t%-16s%-10s%-10s"IP_LF, "Name", "Pkts", "Bytes");
|
||||
ipcom_printf("\t%-16s%-10d%-10d"IP_LF,
|
||||
ipcom_if_indextoname(ipmcp.upstream_if.ifindex, ifname),
|
||||
vif_req.icount,
|
||||
vif_req.ibytes);
|
||||
|
||||
ipcom_printf("Downstream interface IPv4 statistics"IP_LF);
|
||||
ipcom_printf("\t%-16s%-10s%-10s%s"IP_LF, "Name", "Pkts", "Bytes", "State");
|
||||
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
vif_req.vifi = netif->igmp.vif_index;
|
||||
if (ipcom_socketioctl(ipmcp.igmp.fd, IP_SIOCGETVIFCNT, &vif_req) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETVIFCNT failed for upstream interface: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("\t%-16s%-10d%-10d%s"IP_LF,
|
||||
netif->ifname,
|
||||
vif_req.ocount,
|
||||
vif_req.obytes,
|
||||
ipmcp_cmd_link_state_to_str(netif->igmp.state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet_route_cb
|
||||
*===========================================================================
|
||||
* Description: Prints all routes to one IPv4 group.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet_route_cb(Ipmcp_igmp_upstream_maddr_t *maddr, void *unused)
|
||||
{
|
||||
char dst[IP_INET_ADDRSTRLEN];
|
||||
char src[IP_INET_ADDRSTRLEN];
|
||||
int i;
|
||||
struct Ip_sioc_sg_req sg;
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
(void) unused;
|
||||
|
||||
if (&maddr->saddrs[0].s_addr == 0)
|
||||
return;
|
||||
|
||||
ipmcp.log_buf[0] = '\0';
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
if (ipcom_hash_get(netif->igmp.maddr_head, &maddr->maddr))
|
||||
{
|
||||
if (ipmcp.log_buf[0] != '\0')
|
||||
ipcom_strcat(ipmcp.log_buf, ", ");
|
||||
ipcom_strcat(ipmcp.log_buf, netif->ifname);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < IPMCP_IGMP_MAX_SRC_ADDRS; i++)
|
||||
{
|
||||
if (maddr->saddrs[i].s_addr == IP_INADDR_ANY)
|
||||
continue;
|
||||
|
||||
sg.src = maddr->saddrs[i];
|
||||
sg.grp = maddr->maddr;
|
||||
if (ipcom_socketioctl(ipmcp.igmp.fd, IP_SIOCGETSGCNT, &sg) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETSGCNT: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("\t%-20s%-20s%-8d%-8d%s"IP_LF,
|
||||
ipcom_inet_ntop(IP_AF_INET, &maddr->maddr, dst, sizeof(dst)),
|
||||
ipcom_inet_ntop(IP_AF_INET, &maddr->saddrs[i], src, sizeof(src)),
|
||||
sg.pktcnt,
|
||||
sg.bytecnt,
|
||||
ipmcp.log_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet_routes
|
||||
*===========================================================================
|
||||
* Description: Shows all the IPv4 multicast routes.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet_routes(void)
|
||||
{
|
||||
if (ipmcp.upstream_if.igmp.maddr_head)
|
||||
{
|
||||
ipcom_printf("IPv4 routes"IP_LF);
|
||||
ipcom_printf("\t%-20s%-20s%-8s%-8s%s" IP_LF, "Group", "Source", "Pkt", "Bytes", "Dwnstr ifs");
|
||||
ipcom_hash_for_each(ipmcp.upstream_if.igmp.maddr_head,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_inet_route_cb,
|
||||
IP_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet_joined_groups
|
||||
*===========================================================================
|
||||
* Description: Shows all the groups that joined by clients
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet_joined_groups(void)
|
||||
{
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
ipcom_printf("IPv4 groups joined at %s"IP_LF, netif->ifname);
|
||||
if (netif->igmp.maddr_head == IP_NULL || netif->igmp.maddr_head->elem == 0)
|
||||
ipcom_printf("\tNone"IP_LF);
|
||||
else
|
||||
{
|
||||
ipcom_printf("\t%-20s%-8s%s" IP_LF, "Group", "State", "Timer");
|
||||
ipcom_hash_for_each(netif->igmp.maddr_head,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_joined_groups_cb,
|
||||
IP_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* IPMCP_USE_IGMP */
|
||||
|
||||
|
||||
#ifdef IPMCP_USE_MLD
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet6_ifs
|
||||
*===========================================================================
|
||||
* Description: Shows all the IPv6 multicast intefaces.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet6_ifs(void)
|
||||
{
|
||||
struct Ip_sioc_mif_req6 mif_req;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
mif_req.mifi = ipmcp.upstream_if.mld.mif_index;
|
||||
if (ipcom_socketioctl(ipmcp.mld.mrt_fd, IP_SIOCGETMIFCNT_IN6, &mif_req) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETVIFCNT failed for upstream interface: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("Upstream interface IPv6 statistics"IP_LF);
|
||||
ipcom_printf("\t%-16s%-10s%-10s"IP_LF, "Name", "Pkts", "Bytes");
|
||||
ipcom_printf("\t%-16s%-10d%-10d"IP_LF,
|
||||
ipcom_if_indextoname(ipmcp.upstream_if.ifindex, ifname),
|
||||
IP_U64_GETLO(mif_req.icount),
|
||||
IP_U64_GETLO(mif_req.ibytes));
|
||||
|
||||
ipcom_printf("Downstream interface IPv6 statistics"IP_LF);
|
||||
ipcom_printf("\t%-16s%-10s%-10s%s"IP_LF, "Name", "Pkts", "Bytes", "State");
|
||||
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
mif_req.mifi = netif->mld.mif_index;
|
||||
if (ipcom_socketioctl(ipmcp.mld.mrt_fd, IP_SIOCGETMIFCNT_IN6, &mif_req) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETVIFCNT failed for upstream interface: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("\t%-16s%-10d%-10d%s"IP_LF,
|
||||
netif->ifname,
|
||||
IP_U64_GETLO(mif_req.ocount),
|
||||
IP_U64_GETLO(mif_req.obytes),
|
||||
ipmcp_cmd_link_state_to_str(netif->mld.state));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet6_route_cb
|
||||
*===========================================================================
|
||||
* Description: Prints all routes to one IPv6 group.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet6_route_cb(Ipmcp_mld_upstream_maddr_t *maddr, void *unused)
|
||||
{
|
||||
char dst[IP_INET6_ADDRSTRLEN];
|
||||
char src[IP_INET6_ADDRSTRLEN];
|
||||
int i;
|
||||
struct Ip_sioc_sg_req6 sg;
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
(void) unused;
|
||||
|
||||
if (IP_IN6_IS_ADDR_UNSPECIFIED(&maddr->saddrs[0]))
|
||||
return;
|
||||
|
||||
ipcom_memset(&sg, 0, sizeof(sg));
|
||||
sg.src.sin6_family = IP_AF_INET6;
|
||||
IPCOM_SA_LEN_SET(&sg.src, sizeof(sg.src));
|
||||
sg.grp.sin6_family = IP_AF_INET6;
|
||||
IPCOM_SA_LEN_SET(&sg.grp, sizeof(sg.grp));
|
||||
|
||||
ipmcp.log_buf[0] = '\0';
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
if (ipcom_hash_get(netif->mld.maddr_head, &maddr->maddr))
|
||||
{
|
||||
if (ipmcp.log_buf[0] != '\0')
|
||||
ipcom_strcat(ipmcp.log_buf, ", ");
|
||||
ipcom_strcat(ipmcp.log_buf, netif->ifname);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < IPMCP_MLD_MAX_SRC_ADDRS; i++)
|
||||
{
|
||||
if (IP_IN6_IS_ADDR_UNSPECIFIED(&maddr->saddrs[i]))
|
||||
continue;
|
||||
|
||||
sg.src.sin6_addr = maddr->saddrs[i];
|
||||
sg.grp.sin6_addr = maddr->maddr;
|
||||
if (ipcom_socketioctl(ipmcp.mld.mrt_fd, IP_SIOCGETSGCNT_IN6, &sg) < 0)
|
||||
{
|
||||
ipcom_printf("ioctl IP_SIOCGETSGCNT_IN6: %s" IP_LF,
|
||||
ipcom_strerror(ipcom_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
ipcom_printf("\t%-30s%-30s%-8d%-8d%s"IP_LF,
|
||||
ipcom_inet_ntop(IP_AF_INET6, &maddr->maddr, dst, sizeof(dst)),
|
||||
ipcom_inet_ntop(IP_AF_INET6, &maddr->saddrs[i], src, sizeof(src)),
|
||||
IP_U64_GETLO(sg.pktcnt),
|
||||
IP_U64_GETLO(sg.bytecnt),
|
||||
ipmcp.log_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet6_routes
|
||||
*===========================================================================
|
||||
* Description: Shows all the IPv6 multicast routes.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet6_routes(void)
|
||||
{
|
||||
if (ipmcp.upstream_if.mld.maddr_head)
|
||||
{
|
||||
ipcom_printf("IPv6 routes"IP_LF);
|
||||
ipcom_printf("\t%-30s%-30s%-8s%-8s%s" IP_LF, "Group", "Source", "Pkt", "Bytes", "Dwnstr ifs");
|
||||
ipcom_hash_for_each(ipmcp.upstream_if.mld.maddr_head,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_inet6_route_cb,
|
||||
IP_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_inet6_joined_groups
|
||||
*===========================================================================
|
||||
* Description: Shows all the groups that joined by clients
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_inet6_joined_groups(void)
|
||||
{
|
||||
Ipmcp_netif_t *netif;
|
||||
|
||||
for (netif = IPCOM_LIST_FIRST(&ipmcp.downstream_ifs_head);
|
||||
netif;
|
||||
netif = IPCOM_LIST_NEXT(&netif->list))
|
||||
{
|
||||
ipcom_printf("IPv6 groups joined at %s"IP_LF, netif->ifname);
|
||||
if (netif->mld.maddr_head->elem == 0)
|
||||
ipcom_printf("\tNone"IP_LF);
|
||||
else
|
||||
{
|
||||
ipcom_printf("\t%-30s%s" IP_LF, "Group", "State");
|
||||
ipcom_hash_for_each(netif->mld.maddr_head,
|
||||
(Ipcom_hash_foreach_cb_func) ipmcp_cmd_show_joined_groups_cb,
|
||||
IP_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* IPMCP_USE_MLD */
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd_show_usage
|
||||
*===========================================================================
|
||||
* Description: Shows the usage of the multicast proxy shell command.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipmcp_cmd_show_usage(void)
|
||||
{
|
||||
ipcom_printf("Interpeak multicast proxy statistics"IP_LF
|
||||
"usage: "IP_LF
|
||||
" mcastproxy [-4|-6] <-i|-j|-r>"IP_LF
|
||||
" -4 show IPv4 only (default both)"IP_LF
|
||||
" -6 show IPv6 only (default both)"IP_LF
|
||||
" -i show interface statistics"IP_LF
|
||||
" -j show groups joined by clients"IP_LF
|
||||
" -r show route statistics"IP_LF
|
||||
IP_LF
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipmcp_cmd
|
||||
*===========================================================================
|
||||
* Description: Shell command that shows statistics
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipmcp_cmd(int argc, char **argv)
|
||||
{
|
||||
Ipcom_getopt opt;
|
||||
int domain = 0;
|
||||
int cmd = IPMCP_CMD_SHOW_IF_STAT;
|
||||
int c;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
ipmcp_cmd_show_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipcom_getopt_clear_r(&opt);
|
||||
while ((c = ipcom_getopt_r(argc, argv, "46ijr", &opt)) != -1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '4':
|
||||
domain = IP_AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
domain = IP_AF_INET6;
|
||||
break;
|
||||
case 'i':
|
||||
break;
|
||||
case 'j':
|
||||
cmd = IPMCP_CMD_SHOW_JG_STAT;
|
||||
break;
|
||||
case 'r':
|
||||
cmd = IPMCP_CMD_SHOW_RT_STAT;
|
||||
break;
|
||||
default:
|
||||
ipcom_printf("sockperf: unknown option %c"IP_LF, (char)c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
(void)ipcom_mutex_lock(ipmcp.daemon_mutex);
|
||||
|
||||
if (ipcom_ipd_send(IPMCP_IPD_NAME, IPMCP_IPD_EVENT_WAIT_FOR_SHELL_CMD) != IPCOM_SUCCESS)
|
||||
{
|
||||
(void)ipcom_mutex_unlock(ipmcp.daemon_mutex);
|
||||
ipcom_printf("The IPMCP daemon is not running"IP_LF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)ipcom_sem_wait(ipmcp.cmd_sem);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case IPMCP_CMD_SHOW_IF_STAT:
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
if (domain == 0 || domain == IP_AF_INET)
|
||||
ipmcp_cmd_show_inet_ifs();
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
if (domain == 0 || domain == IP_AF_INET6)
|
||||
ipmcp_cmd_show_inet6_ifs();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IPMCP_CMD_SHOW_RT_STAT:
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
if (domain == 0 || domain == IP_AF_INET)
|
||||
ipmcp_cmd_show_inet_routes();
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
if (domain == 0 || domain == IP_AF_INET6)
|
||||
ipmcp_cmd_show_inet6_routes();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IPMCP_CMD_SHOW_JG_STAT:
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
if (domain == 0 || domain == IP_AF_INET)
|
||||
ipmcp_cmd_show_inet_joined_groups();
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
if (domain == 0 || domain == IP_AF_INET6)
|
||||
ipmcp_cmd_show_inet6_joined_groups();
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
(void)ipcom_mutex_unlock(ipmcp.daemon_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp_h.h,v $ $Revision: 1.18.10.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp_h.h,v $
|
||||
* $Author: svc-cmnet $ $Date: 2013-03-13 07:45:29 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPMCP_H_H
|
||||
#define IPMCP_H_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_os.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_tmo2.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
#include "ipmcp_igmp.h"
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
#include "ipmcp_mld.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* IPD name */
|
||||
#define IPMCP_IPD_NAME "ipmcp"
|
||||
/* Tell the daemon to sleep until the shell command has finished */
|
||||
#define IPMCP_IPD_EVENT_WAIT_FOR_SHELL_CMD 100
|
||||
|
||||
/* Syslog */
|
||||
#define IPCOM_SYSLOG_PRIORITY IPMCP_SYSLOG_PRIORITY
|
||||
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPMCP
|
||||
|
||||
|
||||
/* Multicast proxy daeomon states */
|
||||
#define IPMCP_STATE_HALTED (0) /* daemon halted */
|
||||
#define IPMCP_STATE_RUNNING (1) /* daemon running*/
|
||||
#define IPMCP_STATE_WAITING (2) /* waiting for the uplink to become avaiable */
|
||||
|
||||
|
||||
/* Per-link state */
|
||||
#define IPMCP_LINK_STATE_INACTIVE (0) /* not acting as IGMP/MLD router on this link */
|
||||
#define IPMCP_LINK_STATE_NON_QUERIER (1) /* acting as a non-querier */
|
||||
#define IPMCP_LINK_STATE_QUERIER (2) /* acting as a querier */
|
||||
|
||||
/* Link local IP source address availabillity */
|
||||
#define IPMCP_LINK_LOCAL_ADR_NOTAVAIL (-1) /* no link local address available */
|
||||
#define IPMCP_LINK_LOCAL_ADR_AVAIL (0) /* link local address is available on this link */
|
||||
#define IPMCP_LINK_LOCAL_ADR_TENTATIVE (1) /* link local address available, but tentative */
|
||||
|
||||
/* Multicast address state */
|
||||
#define IPMCP_MADDR_STATE_ACTIVE (0) /* Multicast address has listeners */
|
||||
#define IPMCP_MADDR_STATE_LAST_LISTENER (1) /* Multicast address in last listener state */
|
||||
|
||||
/* Address string length for domain unspecific code */
|
||||
#ifdef IPMCP_USE_MLD
|
||||
#define IPMCP_ADDRSTRLEN IP_INET6_ADDRSTRLEN
|
||||
#else
|
||||
#define IPMCP_ADDRSTRLEN IP_INET_ADDRSTRLEN
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_netif_t
|
||||
*===========================================================================
|
||||
* Generic interface data for downstream interface.
|
||||
*/
|
||||
typedef struct Ipmcp_netif_struct
|
||||
{
|
||||
Ipcom_list list;
|
||||
Ip_u32 ifindex;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
Ipmcp_igmp_netif_t igmp;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
Ipmcp_mld_netif_t mld;
|
||||
#endif
|
||||
}
|
||||
Ipmcp_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_upstream_netif_t
|
||||
*===========================================================================
|
||||
* Upstream interface.
|
||||
*/
|
||||
typedef struct Ipmcp_upstream_netif_struct
|
||||
{
|
||||
Ip_u32 ifindex;
|
||||
char ifname[IP_IFNAMSIZ];
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
Ipmcp_igmp_upstream_netif_t igmp;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
Ipmcp_mld_upstream_netif_t mld;
|
||||
#endif
|
||||
}
|
||||
Ipmcp_upstream_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_conf
|
||||
*===========================================================================
|
||||
* Cached configuration values.
|
||||
*/
|
||||
typedef struct Ipmcp_conf_struct
|
||||
{
|
||||
/* Number of resends of membership queries, should be higher for link
|
||||
with high loss probability */
|
||||
Ip_u32 robustness_variable;
|
||||
/* Time, in milliseconds, between membership query requests beeing sent */
|
||||
Ip_u32 query_interval;
|
||||
/* Maximum time, in milliseconds, before the host must answer on a
|
||||
membership query */
|
||||
Ip_u16 query_response_interval;
|
||||
/* The Startup Query Interval is the interval between General Queries
|
||||
sent by a Querier on startup */
|
||||
Ip_u32 startup_query_interval;
|
||||
/* The Startup Query Count is the number of Queries sent out on startup,
|
||||
separated by the Startup Query Interval.*/
|
||||
Ip_u32 startup_query_count;
|
||||
/* The Last Member Query Interval is the Max Response Time used to
|
||||
calculate the Max Resp Code inserted into Group-Specific Queries sent
|
||||
in response to Leave Group messages. It is also the Max Response
|
||||
Time used in calculating the Max Resp Code for Group-and-Source-
|
||||
Specific Query messages. Default: query_interval / 4 msec */
|
||||
Ip_u32 last_member_query_interval;
|
||||
/* The Last Member Query Count is the number of Group-Specific Queries
|
||||
sent before the router assumes there are no local members. The Last
|
||||
Member Query Count is also the number of Group-and-Source-Specific
|
||||
Queries sent before the router assumes there are no listeners for a
|
||||
particular source. Default: the Robustness Variable.*/
|
||||
Ip_u32 last_member_query_count;
|
||||
|
||||
char *downstream_ifs;
|
||||
} Ipmcp_conf_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmlds_data_t
|
||||
*===========================================================================
|
||||
* IPMCP global data.
|
||||
*/
|
||||
typedef struct Ipmcp_data_struct
|
||||
{
|
||||
Ipcom_sem cmd_sem;
|
||||
Ipcom_mutex daemon_mutex;
|
||||
|
||||
/* One of the IPMCP_STATE_xxx states */
|
||||
int state;
|
||||
|
||||
/* IPD socket */
|
||||
Ip_fd ipd_fd;
|
||||
/* Route message socket */
|
||||
Ip_fd rt_fd;
|
||||
|
||||
#ifdef IP_PORT_LAS
|
||||
/* Config socket */
|
||||
Ip_fd cfg_fd;
|
||||
#endif
|
||||
|
||||
/* Timeout queue */
|
||||
Ipcom_pqueue *tmo_head;
|
||||
|
||||
/* Upstream interface, this is the only interface that IPv6 multicast
|
||||
traffic can be forwared from */
|
||||
Ipmcp_upstream_netif_t upstream_if;
|
||||
|
||||
/* interface list */
|
||||
Ipcom_list downstream_ifs_head;
|
||||
|
||||
/* cached configuration variables */
|
||||
Ipmcp_conf_t config;
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
Ipmcp_igmp_data_t igmp;
|
||||
#endif
|
||||
#ifdef IPMCP_USE_MLD
|
||||
Ipmcp_mld_data_t mld;
|
||||
#endif
|
||||
Ip_u32 send_buf[1500 / sizeof(Ip_u32)];
|
||||
Ip_u32 recv_buf[1500/ sizeof(Ip_u32)];
|
||||
char log_buf[100];
|
||||
} Ipmcp_data_t;
|
||||
|
||||
|
||||
IP_EXTERN Ipmcp_data_t ipmcp;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipmcp_netif_t * ipmcp_if_find(Ip_u32 ifindex);
|
||||
IP_GLOBAL void ipmcp_route_init_addrs(void *msg, Ip_u32 addrs, struct Ip_sockaddr **sas);
|
||||
|
||||
#ifdef IPMCP_USE_IGMP
|
||||
IP_GLOBAL int ipmcp_igmp_init(void);
|
||||
IP_GLOBAL void ipmcp_igmp_exit(void);
|
||||
IP_GLOBAL int ipmcp_igmp_if_create(Ipmcp_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_igmp_if_destroy(Ipmcp_netif_t *netif);
|
||||
IP_GLOBAL int ipmcp_igmp_upstream_if_create(Ipmcp_upstream_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_igmp_upstream_if_destroy(Ipmcp_upstream_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_igmp_addr_change(Ipmcp_netif_t *netif, Ip_bool add);
|
||||
IP_GLOBAL int ipmcp_igmp_input(int fd);
|
||||
#endif /* IPMCP_USE_IGMP */
|
||||
|
||||
#ifdef IPMCP_USE_MLD
|
||||
IP_GLOBAL int ipmcp_mld_init(void);
|
||||
IP_GLOBAL void ipmcp_mld_exit(void);
|
||||
IP_GLOBAL int ipmcp_mld_if_create(Ipmcp_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_mld_if_destroy(Ipmcp_netif_t *netif);
|
||||
IP_GLOBAL int ipmcp_mld_upstream_if_create(Ipmcp_upstream_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_mld_upstream_if_destroy(Ipmcp_upstream_netif_t *netif);
|
||||
IP_GLOBAL void ipmcp_mld_addr_change(Ipmcp_netif_t *netif, Ip_bool add);
|
||||
IP_GLOBAL int ipmcp_mld_input(int fd);
|
||||
IP_GLOBAL int ipmcp_mld_mroute_input(int fd);
|
||||
IP_GLOBAL void ipmcp_mld_show_joined_groups_cb(void *obj, void *unused);
|
||||
#endif /* IPMCP_USE_MLD */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp_igmp.h,v $ $Revision: 1.10 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp_igmp.h,v $
|
||||
* $Author: kenneth $ $Date: 2010-12-17 08:56:00 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPMCP_IGMP_H
|
||||
#define IPMCP_IGMP_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#include "ipmcp_mcast.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_igmp_maddr_struct
|
||||
*===========================================================================
|
||||
* IPv4 multicast address descriptor for a downstream interface.
|
||||
* This structure represents a multicast address that has listener on its
|
||||
* link.
|
||||
*/
|
||||
typedef struct Ipmcp_igmp_maddr_struct
|
||||
{
|
||||
Ipmcp_maddr_t base; /* Base class */
|
||||
struct Ip_in_addr maddr;
|
||||
/* Less than max-response-interval has passed since a specific query was sent */
|
||||
Ipcom_tmo2 specific_query_pending_timer;
|
||||
Ipcom_tmo2 v1_host_present_timer; /* In IGMPv1 compatibility mode if this is running */
|
||||
Ipcom_tmo2 v2_host_present_timer; /* In IGMPv2 compatibility mode if this is running */
|
||||
} Ipmcp_igmp_maddr_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_igmp_upstream_maddr
|
||||
*===========================================================================
|
||||
* IPv4 multicast address descriptor for the upstream link.
|
||||
* This structure represents all multicast/source address pairs from which
|
||||
* there is:
|
||||
* - at least one listener on one (or more) of the downstream links
|
||||
* - at least one packet has been received directed to this multicast address
|
||||
* from a sourec now included in the 'saddrs' list.
|
||||
*/
|
||||
typedef struct Ipmcp_igmp_upstream_maddr_struct
|
||||
{
|
||||
Ipmcp_upstream_maddr_t base; /* Base class */
|
||||
struct Ip_in_addr maddr;
|
||||
int next_src_addr;
|
||||
/* Sources from downstream and upstream networks are stored in this array */
|
||||
struct Ip_in_addr saddrs[IPMCP_IGMP_MAX_SRC_ADDRS];
|
||||
}
|
||||
Ipmcp_igmp_upstream_maddr_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_igmp_netif_t
|
||||
*===========================================================================
|
||||
* Downstream IPv4 interface data, the proxy acts as an IGMP router on this
|
||||
* interface.
|
||||
*/
|
||||
typedef struct Ipmcp_igmp_netif_struct
|
||||
{
|
||||
Ip_bool need_if_create;
|
||||
/* One of the IPMCP_LINK_STATE_xxx flags */
|
||||
Ip_u16 state;
|
||||
Ip_u16 robustness_variable;
|
||||
/* Number of queries to send using the Startup Query Interval */
|
||||
Ip_u16 startup_query_count;
|
||||
/* Query interval for this link, in milliseconds */
|
||||
Ip_u32 query_interval;
|
||||
/* Timer for the next query if in querier state,
|
||||
timer when to resume as querier if in non-querier state */
|
||||
Ipcom_tmo2 timer;
|
||||
/* Virtual interface index that maps to this physical interface */
|
||||
Ip_vifi_t vif_index;
|
||||
/* The primary IPv4 address for this interface */
|
||||
struct Ip_in_addr primary_address;
|
||||
/* IPv4 multicast address database */
|
||||
Ipcom_hash *maddr_head;
|
||||
}
|
||||
Ipmcp_igmp_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_igmp_upstream_netif_t
|
||||
*===========================================================================
|
||||
* Upstream IPv4 interface data.
|
||||
*/
|
||||
typedef struct Ipmcp_igmp_upstream_netif_struct
|
||||
{
|
||||
/* The primary IPv4 address for this interface */
|
||||
struct Ip_in_addr primary_address;
|
||||
/* Virtual interface index that maps to this physical interface */
|
||||
Ip_vifi_t vif_index;
|
||||
/* IPv4 multicast address database */
|
||||
Ipcom_hash *maddr_head;
|
||||
}
|
||||
Ipmcp_igmp_upstream_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_igmp_data_t
|
||||
*===========================================================================
|
||||
* Multicast proxy IGMP global data.
|
||||
*/
|
||||
typedef struct Ipmcp_igmp_data_struct
|
||||
{
|
||||
/* Socket used to listen/send IGMP messages on and
|
||||
Multicast forward cache control socket */
|
||||
Ip_fd fd;
|
||||
/* The 224.0.0.1 multicast address */
|
||||
struct Ip_in_addr all_hosts_addr;
|
||||
/* Index of last virtual interface created */
|
||||
Ip_vifi_t last_vifi;
|
||||
/* Method table for Ipmcp_igmp_rec_t class */
|
||||
Ipmcp_rec_ops_t rec_ops;
|
||||
/* Method table for Ipmcp_igmp_saddr_t class */
|
||||
Ipmcp_saddr_ops_t saddr_ops;
|
||||
/* Method table for Ipmcp_igmp_maddr_t class */
|
||||
Ipmcp_maddr_ops_t maddr_ops;
|
||||
/* Method table for Ipmcp_igmp_uplink_maddr_t class */
|
||||
Ipmcp_upstream_maddr_ops_t upstream_maddr_ops;
|
||||
} Ipmcp_igmp_data_t;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp_mcast.h,v $ $Revision: 1.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp_mcast.h,v $
|
||||
* $Author: kenneth $ $Date: 2010-12-17 15:39:19 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPMCP_MCAST_H
|
||||
#define IPMCP_MCAST_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
* Generic functions that can operate on both IPv4 and IPv6 addresses.
|
||||
* Implements most of the processing described in RFC3376 and RFC3810
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_set.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_tmo2.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* IGMPv3 and MLDv2 Group record types */
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_IS_INCLUDE 1
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_IS_EXCLUDE 2
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_CHANGE_TO_INCLUDE_MODE 3
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_CHANGE_TO_EXCLUDE_MODE 4
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_ALLOW_NEW_SOURCES 5
|
||||
#define IPMCP_GROUP_REC_TYPE_MODE_BLOCK_OLD_SOURCES 6
|
||||
|
||||
|
||||
/* Group compatibility modes */
|
||||
#define IPMCP_MCAST_COMPAT_IGMPV1 1
|
||||
#define IPMCP_MCAST_COMPAT_IGMPV2_MLDV1 2
|
||||
#define IPMCP_MCAST_COMPAT_IGMPV3_MLDV2 3
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_rec_t
|
||||
*===========================================================================
|
||||
* Base class for IGMPv3 and MLDv2 membership report record
|
||||
*/
|
||||
struct Ipmcp_rec_struct;
|
||||
#define RTHIS struct Ipmcp_rec_struct *self
|
||||
typedef struct Ipmcp_rec_ops_struct
|
||||
{
|
||||
/* Returns the record type */
|
||||
Ip_u8 (*get_type)(RTHIS);
|
||||
/* Returns a pointer to the group address */
|
||||
void * (*get_maddr)(RTHIS);
|
||||
/* Returns the number of source addresses */
|
||||
unsigned (*get_num_saddrs)(RTHIS);
|
||||
/* Returns a pointer to the source address with index 'i' */
|
||||
void * (*get_saddr)(RTHIS, unsigned i);
|
||||
/* Returns a IPCOM set with all source address in this record */
|
||||
Ipcom_set * (*as_set)(RTHIS);
|
||||
/* Removes all source addresses from the record */
|
||||
void (*clear_source_list)(RTHIS);
|
||||
} Ipmcp_rec_ops_t;
|
||||
|
||||
typedef struct Ipmcp_rec_struct
|
||||
{
|
||||
Ipmcp_rec_ops_t *ops;
|
||||
} Ipmcp_rec_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_saddr_t
|
||||
*===========================================================================
|
||||
* Base class a multicast source address entry
|
||||
*/
|
||||
struct Ipmcp_saddr_struct;
|
||||
#define STHIS struct Ipmcp_saddr_struct *self
|
||||
typedef struct Ipmcp_saddr_ops_struct
|
||||
{
|
||||
void (*dtor)(STHIS);
|
||||
|
||||
void (*set_timer)(STHIS, Ip_u32 msec);
|
||||
void * (*get_addr)(STHIS);
|
||||
} Ipmcp_saddr_ops_t;
|
||||
|
||||
typedef struct Ipmcp_saddr_struct
|
||||
{
|
||||
Ipmcp_saddr_ops_t *ops;
|
||||
Ipcom_tmo2 timer; /* Source timer, entry is remove when this expires */
|
||||
struct Ipmcp_maddr_struct *maddr; /* The multicast address this entry is part of */
|
||||
} Ipmcp_saddr_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_maddr_t
|
||||
*===========================================================================
|
||||
* Base class a multicast address entry
|
||||
*/
|
||||
struct Ipmcp_maddr_struct;
|
||||
#define MTHIS struct Ipmcp_maddr_struct *self
|
||||
typedef struct Ipmcp_maddr_ops_struct
|
||||
{
|
||||
void (*dtor)(MTHIS);
|
||||
|
||||
void * (*get_addr)(MTHIS);
|
||||
int (*compatibility_mode)(MTHIS);
|
||||
|
||||
Ipmcp_saddr_t * (*add_saddr)(MTHIS, IP_CONST void *saddr, Ip_bool is_include_set);
|
||||
Ipmcp_saddr_t * (*get_saddr)(MTHIS, IP_CONST void *saddr, Ip_bool is_include_set);
|
||||
void (*del_saddrs_not_in_rec)(MTHIS, Ipmcp_rec_t *rec, Ip_bool is_include_set);
|
||||
|
||||
void (*send_query)(MTHIS, Ip_u32 max_response_msec, Ipcom_set *saddr_set);
|
||||
|
||||
Ip_u32 (*get_group_timer) (MTHIS);
|
||||
void (*set_group_timer)(MTHIS, Ip_u32 msec);
|
||||
Ip_u32 (*group_membership_interval)(MTHIS);
|
||||
|
||||
void (*update_upstream_if_filter)(MTHIS);
|
||||
} Ipmcp_maddr_ops_t;
|
||||
|
||||
typedef struct Ipmcp_maddr_struct
|
||||
{
|
||||
Ipmcp_maddr_ops_t *ops;
|
||||
int domain;
|
||||
unsigned addr_len; /* Address length for this domain */
|
||||
Ipcom_tmo2 group_timer; /* Will switch to INCLUDE mode when this expires */
|
||||
/* Fields use in specific queries on this group */
|
||||
unsigned query_count; /* Number of times the current specific query will be resent */
|
||||
Ipcom_tmo2 query_timer; /* Will send a specific query when expires */
|
||||
Ip_u8 query_suppress_router_side_processing; /* Set to IP_TRUE if the S bit should be set in
|
||||
the next specific query for this address */
|
||||
|
||||
/* Fields use in source specific queries on this group */
|
||||
Ip_u8 source_query_suppress_router_side_processing; /* Set to IP_TRUE if the S bit should be set in
|
||||
the next source specific query for this address */
|
||||
unsigned source_query_count; /* Number of times the current specific query will be resent */
|
||||
Ipcom_tmo2 source_query_timer; /* Will send a specific query when expires */
|
||||
Ipcom_set *report_set; /* Set of sources to include in the next source specific query */
|
||||
|
||||
/* Multicast source addresses sets */
|
||||
Ip_bool mode_is_include;
|
||||
Ipcom_hash *include_set; /* Set of sources that at least one listener want */
|
||||
Ipcom_hash *exclude_set; /* Set of sources that at least one listener do not want */
|
||||
|
||||
/* Downstream interface for which this entry is valid */
|
||||
struct Ipmcp_netif_struct *netif;
|
||||
} Ipmcp_maddr_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_upstream_maddr_t
|
||||
*===========================================================================
|
||||
* Base class a multicast address entry
|
||||
*/
|
||||
struct Ipmcp_upstream_maddr_struct;
|
||||
#define UTHIS struct Ipmcp_upstream_maddr_struct *self
|
||||
typedef struct Ipmcp_upstream_maddr_ops_struct
|
||||
{
|
||||
void (*dtor)(UTHIS);
|
||||
void * (*get_addr)(UTHIS);
|
||||
void (*change_mode)(UTHIS, Ip_bool to_exclude);
|
||||
void (*add_source)(UTHIS, void *saddr);
|
||||
void (*del_source)(UTHIS, void *saddr);
|
||||
} Ipmcp_upstream_maddr_ops_t;
|
||||
|
||||
typedef struct Ipmcp_upstream_maddr_struct
|
||||
{
|
||||
Ipmcp_upstream_maddr_ops_t *ops; /* Upstream operations */
|
||||
Ipcom_set *filter; /* Current source filter */
|
||||
} Ipmcp_upstream_maddr_t;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL int
|
||||
ipmcp_handle_membership_report_rec(Ipmcp_maddr_t *maddr_obj, Ipmcp_rec_t *rec_obj);
|
||||
|
||||
IP_GLOBAL Ip_u32
|
||||
ipmcp_last_member_query_time(void);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipmcp_update_upstream_if_filter(Ipmcp_upstream_maddr_t *maddr_obj,
|
||||
Ipcom_hash*(*get_maddr_head)(struct Ipmcp_netif_struct *));
|
||||
|
||||
IP_GLOBAL Ip_u32
|
||||
ipmcp_qqic_to_msec(Ip_u8 code);
|
||||
|
||||
IP_GLOBAL Ip_u8
|
||||
ipmcp_qqic_from_msec(Ip_u32 msec, int version);
|
||||
|
||||
/* Source address methods */
|
||||
IP_GLOBAL void
|
||||
ipmcp_saddr_ops_init(Ipmcp_saddr_ops_t *ops);
|
||||
|
||||
|
||||
/* Multicast address methods */
|
||||
IP_GLOBAL void
|
||||
ipmcp_maddr_drop(Ipmcp_maddr_t *maddr, void *unused);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipmcp_maddr_cleanup(Ipmcp_maddr_t *maddr);
|
||||
|
||||
IP_GLOBAL void
|
||||
ipmcp_maddr_ops_init(Ipmcp_maddr_ops_t *ops);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmcp_mld.h,v $ $Revision: 1.8 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipmcp/src/ipmcp_mld.h,v $
|
||||
* $Author: kenneth $ $Date: 2010-12-17 08:56:05 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPMCP_MLD_H
|
||||
#define IPMCP_MLD_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipmcp_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#include "ipmcp_mcast.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_mld_netif_t
|
||||
*===========================================================================
|
||||
* Downstream IPv6 interface data.
|
||||
*/
|
||||
typedef struct Ipmcp_mld_netif_struct
|
||||
{
|
||||
/* One of the IPMCP_LINK_STATE_xxx flags */
|
||||
int no_rt_count;
|
||||
Ip_u16 state;
|
||||
Ip_u16 robustness_variable;
|
||||
Ip_u16 startup_query_count;
|
||||
/* Query interval for this link, in milliseconds */
|
||||
Ip_u32 query_interval;
|
||||
/* Timer for the next query if in querier state,
|
||||
timer when to resume as querier if in non-querier state */
|
||||
Ipcom_tmo2 timer;
|
||||
/* Multicast interface index that maps to this physical interface */
|
||||
Ip_mifi_t mif_index;
|
||||
/* The link local IPv6 address for this interface */
|
||||
struct Ip_in6_addr link_local_address;
|
||||
/* IPv6 multicast address database */
|
||||
Ipcom_hash *maddr_head;
|
||||
}
|
||||
Ipmcp_mld_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_mld_netif_t
|
||||
*===========================================================================
|
||||
* Upstream IPv6 interface data.
|
||||
*/
|
||||
typedef struct Ipmcp_mld_upstream_netif_struct
|
||||
{
|
||||
/* The link local IPv6 address for this interface */
|
||||
struct Ip_in6_addr link_local_address;
|
||||
/* Multicast interface index that maps to this physical interface */
|
||||
Ip_mifi_t mif_index;
|
||||
/* IPv6 multicast address database */
|
||||
Ipcom_hash *maddr_head;
|
||||
}
|
||||
Ipmcp_mld_upstream_netif_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_mld_maddr_t
|
||||
*===========================================================================
|
||||
* MLD multicast address descriptor
|
||||
*/
|
||||
typedef struct Ipmcp_mld_maddr_struct
|
||||
{
|
||||
Ipmcp_maddr_t base; /* Base class */
|
||||
struct Ip_in6_addr maddr;
|
||||
/* Less than max-response-interval has passed since a specific query was sent */
|
||||
Ipcom_tmo2 specific_query_pending_timer;
|
||||
Ipcom_tmo2 v1_host_present_timer; /* In MLDv1 compatibility mode if this is running */
|
||||
} Ipmcp_mld_maddr_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_mld_upstream_maddr
|
||||
*===========================================================================
|
||||
* IPv6 multicast address descriptor for the upstream link.
|
||||
* This structure represents all multicast/source address pairs from which
|
||||
* there is:
|
||||
* - at least one listener on one (or more) of the downstream links
|
||||
* - at least one packet has been received directed to this multicast address
|
||||
* from a sourec now included in the 'saddrs' list.
|
||||
*/
|
||||
typedef struct Ipmcp_mld_upstream_maddr_struct
|
||||
{
|
||||
Ipmcp_upstream_maddr_t base; /* Base class */
|
||||
struct Ip_in6_addr maddr;
|
||||
int next_src_addr;
|
||||
/* Sources from downstream and upstream networks are stored in this array */
|
||||
struct Ip_in6_addr saddrs[IPMCP_MLD_MAX_SRC_ADDRS];
|
||||
}
|
||||
Ipmcp_mld_upstream_maddr_t;
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipmcp_mld_data_t
|
||||
*===========================================================================
|
||||
* Multicast proxy MLD global data.
|
||||
*/
|
||||
typedef struct Ipmcp_mld_data_struct
|
||||
{
|
||||
/* Socket used to listen/send MLD messages on */
|
||||
Ip_fd mld_fd;
|
||||
/* Multicast forward cache control socket */
|
||||
Ip_fd mrt_fd;
|
||||
/* The ff02::1 multicast address */
|
||||
struct Ip_in6_addr all_hosts_addr;
|
||||
/* Index of last multicast interface created */
|
||||
Ip_mifi_t last_mifi;
|
||||
/* Method table for Ipmcp_mld_rec_t class */
|
||||
Ipmcp_rec_ops_t rec_ops;
|
||||
/* Method table for Ipmcp_mld_saddr_t class */
|
||||
Ipmcp_saddr_ops_t saddr_ops;
|
||||
/* Method table for Ipmcp_mld_maddr_t class */
|
||||
Ipmcp_maddr_ops_t maddr_ops;
|
||||
/* Method table for Ipmcp_mld_uplink_maddr_t class */
|
||||
Ipmcp_upstream_maddr_ops_t upstream_maddr_ops;
|
||||
} Ipmcp_mld_data_t;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user