original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,463 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iprip_cmd_ripctrl.c,v $ $Revision: 1.18.12.2 $
* $Source: /home/interpeak/CVSRoot/iprip/src/iprip_cmd_ripctrl.c,v $
* $Author: hxie $ $Date: 2012-04-27 08:40:22 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
* Implementation of ripctrl shell command to use for IPRIP testing
* or telnet shell management.
*
* 'ripctrl' A command to print and manage RIP route entries as well
* as bring up and take down RIP interfaces.
*
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "iprip_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_ANDORNOT
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_getopt.h>
#include "iprip.h"
/* Syslog priority and facility. */
#if defined(_WRS_CONFIG_IPRIP_SYSLOG_PRIORITY)
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPRIP_SYSLOG_PRIORITY
#else
#define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_PRIO_DEFAULT
#endif
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPRIP
/*
****************************************************************************
* 4 EXTERN PROTOTYPES
****************************************************************************
*/
IP_GLOBAL Ip_err iprip_ifattach(const char *ifname, const char *confstr);
IP_GLOBAL Ip_err iprip_ifdetach(const char *ifname);
IP_GLOBAL Ip_err iprip_open_interface(Ip_fd fd, const char *ifname, Ip_bool multicast, Ip_s32 authtype);
/*
****************************************************************************
* 5 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 6 TYPES
****************************************************************************
*/
/*
*===========================================================================
* Iprip_rtprint_arg
*===========================================================================
* Used to pass more than one argument to the iprip_rtwalk() callback.
*/
typedef struct Iprip_rtprint_arg_struct
{
Ip_s32 num;
}
Iprip_rtprint_arg;
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC int iprip_cmd_ripctrl(int argc, char **argv);
/* RIPCTRL functions. */
IP_STATIC Ip_s32 iprip_ripctrl_addrlen(Ip_u32 mask);
IP_STATIC int iprip_ripctrl_fillrt(int argc, char **argv, Iprip_route *rt);
IP_STATIC int iprip_ripctrl_rtprint(void *cookie, Iprip_rt *rt);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC char iprip_cmd_str[16];
/*
****************************************************************************
* 9 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iprip_ripctrl_addrlen
*===========================================================================
* Description: Return the length of an IP mask.
* Parameters: mask A route mask in host endian.
* Returns: Key length, i.e. number of contiguous bits set in the mask.
*
*/
IP_STATIC Ip_s32
iprip_ripctrl_addrlen(Ip_u32 mask)
{
Ip_s32 n, bits;
for (bits = 0, n = 31; n >= 0; bits++, n--)
if (!IP_BIT_GET(mask, n))
break;
return bits;
}
/*
*===========================================================================
* iprip_ripctrl_fillrt
*===========================================================================
* Description: Get Route information and options from command line options.
* Parameters: argc Number of command line arguments.
* argv Array of command line string.
* rt Pointer to 'Iprip_rt' structure to store the output.
* Returns: 0 for success else -1.
*
*
*/
IP_STATIC int
iprip_ripctrl_fillrt(int argc, char **argv, Iprip_route *rt)
{
int c;
Ipcom_getopt opt;
struct Ip_in_addr inaddr;
/* Optional arguments. */
ipcom_getopt_clear_r(&opt);
while((c = ipcom_getopt_r(argc - 1, argv + 1, "m:r:p", &opt)) != -1)
{
switch (c)
{
case 'm':
rt->metric = ipcom_atoi(opt.optarg);
break;
case 'r':
rt->routetag = (Ip_u16)ipcom_atoi(opt.optarg);
break;
case 'p':
IP_BIT_SET(rt->flags, IPRIP_ROUTE_FLAG_PERMANENT);
break;
default:
return -1;
}
}
opt.optind++;
switch(argc - opt.optind)
{
case 1:
ipcom_printf("ripctrl: missing <m.a.s.k>"IP_LF);
return -1;
case 3:
if (ipcom_inet_pton(IP_AF_INET, argv[opt.optind + 2], &inaddr) != 1)
{
ipcom_printf("ripctrl: badly formated [ga.te.wa.y] IP address."IP_LF);
return -1;
}
rt->router_n = inaddr.s_addr;
case 2: /*lint !e616 control flows into case/default */
if (ipcom_inet_pton(IP_AF_INET, argv[opt.optind], &inaddr) != 1)
{
ipcom_printf("ripctrl: badly formated <d.e.s.t> IP address."IP_LF);
return -1;
}
rt->ipaddr_n = inaddr.s_addr;
if (ipcom_inet_pton(IP_AF_INET, argv[opt.optind + 1], &inaddr) != 1)
{
ipcom_printf("ripctrl: badly formated <m.a.s.k> IP address."IP_LF);
return -1;
}
rt->mask_n = inaddr.s_addr;
break;
default:
return -1;
}
/* success. */
return 0;
}
/*
*===========================================================================
* iprip_ripctrl_rtprint
*===========================================================================
* Description: iprip_rtwalk() callback function to print a RIP route.
* Parameters: rt IPRIP Route pointer.
* cookie Iprip_rtprint_arg pointer to hold the func args.
* Returns: 0 to parse all routes and delete none.
*
*/
IP_STATIC int
iprip_ripctrl_rtprint(void *cookie, Iprip_rt *rt)
{
char buf[32];
((Iprip_rtprint_arg *)cookie)->num++;
ipcom_sprintf(buf, "%s/%ld",
ipcom_inet_ntop(IP_AF_INET, &rt->ipaddr_n, iprip_cmd_str, 16),
iprip_ripctrl_addrlen((Ip_u32)IP_SWAP32(rt->mask_n)));
ipcom_printf("%-18s ", buf);
ipcom_printf("%-15s ", ipcom_inet_ntop(IP_AF_INET, &rt->router_n, iprip_cmd_str, 16));
ipcom_printf("%-7ld ", rt->metric);
ipcom_printf("%-11s", ipcom_if_indextoname(rt->ifindex, buf));
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_STACKROUTE) ? "R" : " ");
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_GARBAGE) ? "G" : " ");
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_STATIC) ? "S" : " ");
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_PERMANENT) ? "P" : " ");
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_INTERFACE) ? "I" : " ");
ipcom_printf("%s", IP_BIT_ISSET(rt->flags, IPRIP_ROUTE_FLAG_LEAKED) ? "L" : " ");
ipcom_printf(" %-4d", rt->age);
ipcom_printf(IP_LF);
return 0;
}
/*
*===========================================================================
* iprip_cmd_ripctrl
*===========================================================================
* Description: The 'ripctrl' shell command. A command to print, add,
* and delete RIP routes as well as open and close RIP
* interfaces.
* Parameters: Standard argc, argv
* Returns: 0.
*
*/
IP_PUBLIC int
iprip_cmd_ripctrl(int argc, char **argv)
{
Ip_err retval;
char ripconf[256];
ripconf[0] = '\0';
if (iprip_socket() == IP_INVALID_SOCKET)
{
ipcom_printf("The IPRIP daemon is not running"IP_LF);
return 0;
}
if (argc == 1)
goto usage;
/*********** [rt]print ***********/
if (ipcom_strcmp(argv[1], "rtprint") == 0 || ipcom_strcmp(argv[1], "print") == 0)
{
Iprip_rtprint_arg arg;
arg.num = 0;
if (argc != 2)
goto usage;
ipcom_printf("Destination Gateway Metric Interface Flags Age"IP_LF);
(void)iprip_rtwalk(&arg, iprip_ripctrl_rtprint);
ipcom_printf("Total of %ld RIP entries."IP_LF, arg.num);
ipcom_printf("Flags: I=interface, P=permanent, S=static, G=garbage, R=stackroute, L=leaked"IP_LF);
}
/*********** add ***********/
else if (ipcom_strcmp(argv[1], "rtadd") == 0)
{
Iprip_route rt;
ipcom_memset(&rt, 0, sizeof(Iprip_route));
rt.metric = 1;
IP_BIT_SET(rt.flags, IPRIP_ROUTE_FLAG_STATIC);
if (iprip_ripctrl_fillrt(argc, argv, &rt) != 0)
{
ipcom_fprintf(ip_stderr, "ripctrl: invalid argument format, check usage."IP_LF);
goto usage;
}
ipcom_printf("Adding static RIP route: %s",
ipcom_inet_ntop(IP_AF_INET, &rt.ipaddr_n, iprip_cmd_str, 16));
ipcom_printf("/%s -> ",
ipcom_inet_ntop(IP_AF_INET, &rt.mask_n, iprip_cmd_str, 16));
ipcom_printf("%s, metric %ld, tag %d"IP_LF,
ipcom_inet_ntop(IP_AF_INET, &rt.router_n, iprip_cmd_str, 16),
rt.metric, (Ip_u16)rt.routetag);
retval = iprip_rtadd(&rt);
if (retval == IPCOM_SUCCESS)
ipcom_printf(" ok"IP_LF);
else
ipcom_fprintf(ip_stderr, " failed : %s [%d]"IP_LF,
ipcom_err_string(retval), retval);
}
/*********** delete ***********/
else if (ipcom_strcmp(argv[1], "rtdelete") == 0)
{
Iprip_route rt;
ipcom_memset(&rt, 0, sizeof(Iprip_route));
if (iprip_ripctrl_fillrt(argc, argv, &rt) != 0)
{
ipcom_fprintf(ip_stderr, "ripctrl: invalid argument format, check usage."IP_LF);
goto usage;
}
ipcom_printf("Deleting static RIP route: %s",
ipcom_inet_ntop(IP_AF_INET, &rt.ipaddr_n, iprip_cmd_str, 16));
ipcom_printf("/%s -> ",
ipcom_inet_ntop(IP_AF_INET, &rt.mask_n, iprip_cmd_str, 16));
ipcom_printf("%s, metric %ld, tag %d"IP_LF,
ipcom_inet_ntop(IP_AF_INET, &rt.router_n, iprip_cmd_str, 16),
rt.metric, (Ip_u16)rt.routetag);
retval = iprip_rtdelete(&rt);
if (retval == IPCOM_SUCCESS)
ipcom_printf(" ok"IP_LF);
else
ipcom_fprintf(ip_stderr, " failed : %s [%d]"IP_LF,
ipcom_err_string(retval), retval);
}
/*********** ifopen ***********/
else if (ipcom_strcmp(argv[1], "ifopen") == 0)
{
if (argc < 4)
ipcom_fprintf(ip_stderr, "usage: ripctrl ifopen <interface name> [options]"IP_LF
" options: [broadcast|multicast|silent] [in-multi] [auth-simple|auth-md5 <pwd>] [out v1] [in no|v1|v2] [nopoison]"IP_LF);
else
{
int i, len;
len = ipcom_sprintf(ripconf, "%s", argv[2]);
for (i = 3; i < argc; i++)
{
if (!ipcom_strcmp(argv[i], "broadcast") || !ipcom_strcmp(argv[i], "multicast") || !ipcom_strcmp(argv[i], "silent"))
{
len += ipcom_sprintf(ripconf + len, " %s", argv[i]);
continue;
}
if (!ipcom_strcmp(argv[i], "in-multi"))
{
len += ipcom_sprintf(ripconf + len, " input-multicast");
continue;
}
if ((!ipcom_strcmp(argv[i], "auth-md5") || !ipcom_strcmp(argv[i], "auth-simple")) && i++ < argc)
{
len += ipcom_sprintf(ripconf + len, " %s=%s", argv[i - 1], argv[i]);
continue;
}
if (!ipcom_strcmp(argv[i], "out") && ++i < argc && !ipcom_strcmp(argv[i], "v1"))
{
len += ipcom_sprintf(ripconf + len, " version-1");
continue;
}
if (!ipcom_strcmp(argv[i], "in") && ++i < argc && (!ipcom_strcmp(argv[i], "no") || !ipcom_strcmp(argv[i], "v1") || !ipcom_strcmp(argv[i], "v2")))
{
len += ipcom_sprintf(ripconf + len, " input=%s", argv[i]);
continue;
}
if (!ipcom_strcmp(argv[i], "nopoison"))
{
len += ipcom_sprintf(ripconf + len, " nopoison");
continue;
}
goto usage;
}
retval = iprip_ifattach(argv[2], ripconf);
if (retval == IPCOM_SUCCESS)
ipcom_printf(" ok"IP_LF);
else
ipcom_fprintf(ip_stderr, " failed : %s [%d]"IP_LF,
ipcom_err_string(retval), retval);
}
}
/*********** ifclose ***********/
else if (ipcom_strcmp(argv[1], "ifclose") == 0)
{
if (argc != 3)
ipcom_fprintf(ip_stderr, "usage: ripctrl ifclose <interface name, e.g. eth0>"IP_LF);
else
{
retval = iprip_ifdetach(argv[2]);
if (retval == IPCOM_SUCCESS)
ipcom_printf(" ok"IP_LF);
else
ipcom_fprintf(ip_stderr, " failed : %s [%d]"IP_LF,
ipcom_err_string(retval), retval);
}
}
else
{
goto usage;
}
return 0;
usage:
ipcom_printf("Interpeak RIP control, version 1.2"IP_LF
"Copyright (c) 2000-2007, Interpeak AB <www.interpeak.com>"IP_LF
"usage: ripctrl rtprint"IP_LF
" rtadd [-m metric] [-r tag] [-p] <d.e.s.t> <m.a.s.k> [ga.te.wa.y]"IP_LF
" rtdelete <d.e.s.t> <m.a.s.k> [gateway]"IP_LF
" ifopen <ifname> [options] (type 'ifopen ifname' to see options)"IP_LF
" ifclose <ifname>"IP_LF);
return 0;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,952 @@
/*
******************************************************************************
* INTERPEAK EXAMPLE SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iprip_daemon.c,v $ $Revision: 1.25.2.1 $
* $Source: /home/interpeak/CVSRoot/iprip/src/iprip_daemon.c,v $
* $Author: hxie $
* $State: Exp $ $Locker: $
*
* Copyright 2000-2007 Interpeak AB (http://www.interpeak.se). All rights reserved.
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "iprip_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_inet.h>
#include <ipcom_syslog.h>
#include <ipcom_ipd.h>
#include <ipnet_config.h>
#include <ipnet.h>
#include <ipnet_routesock.h>
#include <ipnet_cmd.h>
#include "iprip.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#ifndef IPNET
#error IPRIP_REQUIRES_IPNET
#endif
#define IPNET_IF_LOOPBACK_INDEX 1 /* The index of the loopback interface */
/* Syslog priority and facility. */
#if defined(_WRS_CONFIG_IPRIP_SYSLOG_PRIORITY)
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPRIP_SYSLOG_PRIORITY
#else
#define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_PRIO_DEFAULT
#endif
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPRIP
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
IP_EXTERN IP_CONST char *iprip_staticroute_config[];
IP_GLOBAL char *iprip_ifgetconf(const char *ifname);
IP_GLOBAL const char *iprip_ifgetconfopt(const char *confstr, char *option);
IP_GLOBAL Ip_err iprip_ifattach(const char *ifname, const char *confstr);
IP_GLOBAL Ip_err iprip_ifdetach(const char *ifname);
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_STATIC Ip_err iprip_write(Ip_fd udp_fd, void *cookie, Ip_u32 ipaddr_n, Ipcom_sock_addr *dest, void *buf, Ip_size_t len);
IP_STATIC Ip_err iprip_add_route_rtsock(void *cookie, Iprip_rt *rt);
IP_STATIC Ip_err iprip_delete_route_rtsock(void *cookie, Iprip_rt *rt);
IPCOM_PROCESS(ipripd);
IP_PUBLIC Ip_err iprip_create(void);
IP_PUBLIC Ip_err iprip_start(void);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC char iprip_dstr[16];
#if IPRIP_SYSLOG_PRIORITY >= IPCOM_LOG_DEBUG2
IP_STATIC Ipcom_cmd_int_str_map iprip_rtm_map[] =
{
{ IPNET_RTM_ADD, "ADD" },
{ IPNET_RTM_DELETE, "DELETE" },
{ IPNET_RTM_CHANGE, "CHANGE" },
{ IPNET_RTM_GET, "GET" },
{ IPNET_RTM_LOOSING, "LOOSING" },
{ IPNET_RTM_REDIRECT, "REDIRECT" },
{ IPNET_RTM_MISS, "MISS" },
{ IPNET_RTM_LOCK, "LOCK" },
{ IPNET_RTM_RESOLVE, "RESOLVE" },
{ IPNET_RTM_NEWADDR, "NEWADDR" },
{ IPNET_RTM_DELADDR, "DELADDR" },
{ IPNET_RTM_IFINFO, "IFINFO" },
{ -1, IP_NULL }
};
IP_STATIC Ipcom_cmd_int_str_map iprip_rta_map[] =
{
{ IPNET_RTAX_DST, "DST" },
{ IPNET_RTAX_GATEWAY, "GATEWAY" },
{ IPNET_RTAX_NETMASK, "NETMASK" },
{ IPNET_RTAX_GENMASK, "GENMASK" },
{ IPNET_RTAX_IFP, "IFP" },
{ IPNET_RTAX_IFA, "IFA" },
{ IPNET_RTAX_AUTHOR, "AUTHOR" },
{ IPNET_RTAX_BRD, "BRD" },
{ -1, IP_NULL }
};
#endif
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iprip_rtmsg_print_addresses
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
#if IPRIP_SYSLOG_PRIORITY >= IPCOM_LOG_DEBUG2
IP_STATIC void
iprip_rtmsg_print_addresses(int addrs, struct Ip_sockaddr *first)
{
struct Ip_sockaddr *addr_ptr;
int i;
char addr_str[40];
char buf[10];
addr_ptr = first;
for (i = 0; i < IPNET_RTAX_MAX; i++)
{
if (IP_BIT_ISSET(addrs, 1 << i))
{
if (ipcom_cmd_sockaddr_to_str(addr_ptr, IP_FALSE, IP_TRUE, addr_str, sizeof(addr_str)) == IP_NULL)
{
/* Invalid address */
IP_PANIC2();
continue;
}
IPCOM_LOG2(DEBUG2, " " "%-10s: %s",
ipcom_cmd_key_to_str(iprip_rta_map, i, buf, sizeof(buf)),
addr_str);
addr_ptr = (struct Ip_sockaddr *) ((Ip_u8*) addr_ptr + IPCOM_SA_LEN_GET(addr_ptr));
}
}
}
#endif
/*
*===========================================================================
* iprip_rtsock_adddel
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
iprip_rtsock_adddel(Ip_fd rt_fd, Iprip_rt *rt, Ip_bool add)
{
struct Ip_sockaddr_in *sockaddr;
Ip_ssize_t length;
struct rtmsg_buf_struct
{
struct Ipnet_rt_msghdr msghdr;
struct Ip_sockaddr_in sin[3];
} rtmsg_buf;
static Ip_u32 seq;
char iprip_dstr2[16];
char iprip_dstr3[16];
IPCOM_LOG6(DEBUG2,
" ++ %s_route(): %s"
"/%s, metric=%ld, flags=0x%x"
" -> %s.",
add ? "add" : "delete",
ipcom_inet_ntop(IP_AF_INET, &rt->ipaddr_n, iprip_dstr, 16),
ipcom_inet_ntop(IP_AF_INET, &rt->mask_n, iprip_dstr2, 16),
rt->metric, rt->flags,
ipcom_inet_ntop(IP_AF_INET, &rt->router_n, iprip_dstr3, 16));
(void)iprip_dstr2;
(void)iprip_dstr3;
ipcom_memset(&rtmsg_buf, 0, sizeof(struct rtmsg_buf_struct));
sockaddr = rtmsg_buf.sin;
rtmsg_buf.msghdr.rtm_msglen = sizeof(struct Ipnet_rt_msghdr);
rtmsg_buf.msghdr.rtm_version = IPNET_RTM_VERSION;
rtmsg_buf.msghdr.rtm_type = (Ip_u8)(add ? IPNET_RTM_ADD : IPNET_RTM_DELETE);
rtmsg_buf.msghdr.rtm_table = 0;
rtmsg_buf.msghdr.rtm_flags = IPNET_RTF_GATEWAY | IPNET_RTF_UP | IPNET_RTF_DONE | IPNET_RTF_DYNAMIC;
rtmsg_buf.msghdr.rtm_addrs = 0;
rtmsg_buf.msghdr.rtm_pid = ipcom_getpid();
rtmsg_buf.msghdr.rtm_seq = ++seq;
rtmsg_buf.msghdr.rtm_rmx.rmx_rtt = 0; /* not used. */
rtmsg_buf.msghdr.rtm_rmx.rmx_rttvar = 0; /* not used. */
rtmsg_buf.msghdr.rtm_rmx.rmx_mtu = 0; /* use interface mtu. */
rtmsg_buf.msghdr.rtm_rmx.rmx_hopcount = (Ip_u32)rt->metric;
rtmsg_buf.msghdr.rtm_rmx.rmx_expire = IPCOM_ADDR_INFINITE;
/* Add route destination. */
IPCOM_SA_LEN_SET(sockaddr, sizeof(struct Ip_sockaddr_in));
sockaddr->sin_family = IP_AF_INET;
sockaddr->sin_addr.s_addr = rt->ipaddr_n;
rtmsg_buf.msghdr.rtm_msglen = (Ip_u16)(rtmsg_buf.msghdr.rtm_msglen + sizeof(struct Ip_sockaddr_in));
rtmsg_buf.msghdr.rtm_addrs |= IPNET_RTA_DST;
sockaddr++;
/* Add gateway if non zero. */
if (rt->router_n != 0)
{
IPCOM_SA_LEN_SET(sockaddr, sizeof(struct Ip_sockaddr_in));
sockaddr->sin_family = IP_AF_INET;
sockaddr->sin_addr.s_addr = rt->router_n;
rtmsg_buf.msghdr.rtm_msglen = (Ip_u16)(rtmsg_buf.msghdr.rtm_msglen + sizeof(struct Ip_sockaddr_in));
rtmsg_buf.msghdr.rtm_addrs |= IPNET_RTA_GATEWAY;
sockaddr++;
}
/* Add mask if network (non-host) route. */
if (rt->mask_n != 0xffffffff)
{
IPCOM_SA_LEN_SET(sockaddr, sizeof(struct Ip_sockaddr_in));
sockaddr->sin_family = IP_AF_INET;
sockaddr->sin_addr.s_addr = rt->mask_n;
rtmsg_buf.msghdr.rtm_msglen = (Ip_u16)(rtmsg_buf.msghdr.rtm_msglen + sizeof(struct Ip_sockaddr_in));
rtmsg_buf.msghdr.rtm_addrs |= IPNET_RTA_NETMASK;
}
else
rtmsg_buf.msghdr.rtm_flags |= IPNET_RTF_HOST;
/* Add/delete the route with IPNET. */
length = ipcom_send(rt_fd, &rtmsg_buf, rtmsg_buf.msghdr.rtm_msglen, 0);
if (length != rtmsg_buf.msghdr.rtm_msglen)
{
IPCOM_LOG2(DEBUG2, "failed to add route %s, errno = %d",
iprip_routeinfo(rt), ipcom_errno);
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* iprip_add_route_rtsock
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
iprip_add_route_rtsock(void *cookie, Iprip_rt *rt)
{
#if WRS_CONFIG_LP64
assert(((long)cookie & 0xffffffff00000000) == 0);
#endif
return iprip_rtsock_adddel((Ip_fd)(long)cookie, rt, IP_TRUE);
}
/*
*===========================================================================
* iprip_delete_route_rtsock
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
iprip_delete_route_rtsock(void *cookie, Iprip_rt *rt)
{
#if WRS_CONFIG_LP64
assert(((long)cookie & 0xffffffff00000000) == 0);
#endif
return iprip_rtsock_adddel((Ip_fd)(long)cookie, rt, IP_FALSE);
}
/*
*===========================================================================
* iprip_write
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
iprip_write(Ip_fd udp_fd, void *cookie, Ip_u32 ipaddr_n, Ipcom_sock_addr *dest, void *buf, Ip_size_t len)
{
struct Ip_sockaddr_in faddr;
(void)cookie;
/* RIP multicast address, must set outgoing interface index in socket. */
if (dest->ipaddr_n == IPRIP_MADDR) /* 224.0.0.9 */
{
struct Ip_in_addr inaddr;
inaddr.s_addr = ipaddr_n;
if (ipcom_setsockopt(udp_fd, IP_IPPROTO_IP, IP_IP_MULTICAST_IF, &inaddr, sizeof(Ip_socklen_t)) == IP_SOCKERR)
{
IP_PANIC2();
}
}
/* Copy over the destination address in a socket address structure. */
ipcom_memset(&faddr, 0, sizeof(faddr));
faddr.sin_family = IP_AF_INET;
IPCOM_SA_LEN_SET(&faddr, sizeof(struct Ip_sockaddr_in));
faddr.sin_addr.s_addr = dest->ipaddr_n;
faddr.sin_port = dest->port_n;
/* Use sendto() to transmit the UDP packet. */
if (ipcom_sendto(udp_fd, buf, (Ip_size_t)len, 0, (IP_CONST struct Ip_sockaddr *)&faddr, sizeof(faddr)) < 0)
{
Ip_socklen_t errlen;
int so_errno;
char ifname[IP_IFNAMSIZ];
errlen = sizeof(int);
IPCOM_LOG3(ERR, "iprip_write() :: failed to send RIP packet to %s on %s, errno = %d",
ipcom_inet_ntop(IP_AF_INET, &dest->ipaddr_n, iprip_dstr, 16),
ipcom_if_indextoname(dest->ifindex, ifname),
ipcom_errno);
/* Clear socket error */
(void)ipcom_getsockopt(udp_fd, IP_SOL_SOCKET, IP_SO_ERROR, &so_errno, &errlen);
return -1;
}
/* success. */
return 0;
}
/*
*===========================================================================
* ipripd
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IPCOM_PROCESS(ipripd)
{
Ip_err ret;
Iprip_open conf;
Ip_fd udp_fd;
Ip_fd rt_fd = IP_INVALID_SOCKET;
Ip_fd ipd_fd = IP_INVALID_SOCKET;
Ip_pid_t ipripd_pid;
struct Ip_sockaddr_in addr;
struct Ip_sockaddr *sap_dst;
struct Ip_sockaddr *sap_gateway;
struct Ip_sockaddr *sap_netmask;
struct Ip_sockaddr *sap_ifp;
struct Ip_sockaddr *sap_ifa;
Ip_u32 org_offset, cur_offset;
Ip_fd_set read_set;
int optval, num, max;
Ip_ssize_t length;
Ip_bool iprip_init_ok = IP_FALSE;
Ip_bool iprip_open_ok = IP_FALSE;
struct Ip_msghdr msghdr;
struct Ip_iovec iovec;
struct Ip_in_pktinfo *pktinfop;
struct Ip_if_nameindex *oifrs, *ifrs;
char *ripconf;
int addrs;
Iprip_route route;
char option[64];
union Membuf_union
{
struct Ip_cmsghdr cm;
struct Ipnet_rt_msghdr rtmsg;
struct Ipnet_if_msghdr ifmsg;
struct Ipnet_ifa_msghdr ifamsg;
char control[IP_CMSG_SPACE(sizeof(struct Ip_in_addr)) + IP_CMSG_SPACE(sizeof(struct Ip_in_pktinfo))];
struct rtmsg_buf_struct
{
struct Ipnet_rt_msghdr msghdr;
struct Ip_sockaddr_in sin[4];
} rtmsg_buf;
struct rtmsg2_buf_struct
{
struct Ipnet_rt_msghdr msghdr;
struct Ip_sockaddr_in dst[1];
struct Ip_sockaddr_dl gateway[1];
struct Ip_sockaddr_dl ifp[1];
struct Ip_sockaddr_in ifa[1];
} rtmsg2_buf;
struct rtmsg3_buf_struct
{
struct Ipnet_rt_msghdr msghdr;
struct Ip_sockaddr_in dst[1];
struct Ip_sockaddr_in gateway[1];
struct Ip_sockaddr_in netmask[1];
struct Ip_sockaddr_dl ifp[1];
struct Ip_sockaddr_in ifa[1];
Ip_u32 filler[2];
} rtmsg3_buf;
char offset[1];
} membuf;
#if IPRIP_SYSLOG_PRIORITY >= IPCOM_LOG_DEBUG2
Ip_time_t start;
char buf[10];
#endif
ipcom_proc_init();
IPCOM_LOG0(INFO, "ipripd :: starting");
#if IPRIP_SYSLOG_PRIORITY >= IPCOM_LOG_DEBUG2
start = ipcom_time(0);
#endif
ipripd_pid = ipcom_getpid();
pktinfop = (struct Ip_in_pktinfo *)(membuf.control + IP_CMSG_ALIGN(sizeof(struct Ip_cmsghdr)));
iovec.iov_base = IP_NULL;
/* Get RIP UDP socket. */
udp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
if (udp_fd == IP_INVALID_SOCKET)
{
IPCOM_LOG1(ERR, "ipripd :: ipcom_socket(IP_SOCK_DGRAM) failed, errno = %d", ipcom_errno);
goto badout;
}
/* Enable receive interface index on UDP socket. */
optval = 1;
if (ipcom_setsockopt(udp_fd, IP_IPPROTO_IP, IP_IP_PKTINFO, (IP_CONST void *)&optval, sizeof(Ip_socklen_t)) == IP_SOCKERR)
{
IPCOM_LOG1(ERR, "ipripd :: ipcom_setsockopt(IP_IP_PKTINFO) failed, errno = %d", ipcom_errno);
goto badout;
}
/* Enable broadcasting on socket. */
#ifdef IP_SO_BROADCAST
optval = 1;
if (ipcom_setsockopt(udp_fd, IP_SOL_SOCKET, IP_SO_BROADCAST, (IP_CONST void *)&optval, sizeof(Ip_socklen_t)) == IP_SOCKERR)
{
IPCOM_LOG1(ERR, "ipripd :: ipcom_setsockopt(IP_SO_BROADCAST) failed, errno = %d", ipcom_errno);
goto badout;
}
#endif
/* Bind to RIP port. */
ipcom_memset(&addr, 0, sizeof(addr));
addr.sin_family = IP_AF_INET;
IPCOM_SA_LEN_SET(&addr, sizeof(struct Ip_sockaddr_in));
addr.sin_addr.s_addr = IP_INADDR_ANY;
addr.sin_port = ip_htons(520);
if (ipcom_bind(udp_fd, (struct Ip_sockaddr *)&addr, sizeof(addr)) == IP_SOCKERR)
{
IPCOM_LOG1(ERR, "ipripd :: ipcom_bind(520) failed, errno = %d", ipcom_errno);
goto badout;
}
/* Get routing socket. */
rt_fd = ipcom_socket(IP_AF_ROUTE, IP_SOCK_RAW, 0);
if (rt_fd == IP_INVALID_SOCKET)
{
IPCOM_LOG1(ERR, "ipripd :: ipcom_socket(IP_SOCK_RAW) failed, errno = %d", ipcom_errno);
goto badout;
}
iovec.iov_base = ipcom_malloc(1500);
if (iovec.iov_base == IP_NULL)
{
IP_PANIC2();
IPCOM_LOG0(ERR, "ipripd :: ipcom_malloc(1500) failed, out of memory");
goto badout;
}
/***** Initialize IPRIP. *****/
ret = iprip_init();
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipripd :: iprip_init() failed, err = %ld", ret);
goto badout;
}
iprip_init_ok = IP_TRUE;
/***** Open and configure IPRIP. *****/
conf.udp_fd = udp_fd;
conf.cookie = (void *)(long)rt_fd;
conf.rip_write = iprip_write;
conf.add_route = iprip_add_route_rtsock;
conf.delete_route = iprip_delete_route_rtsock;
conf.conf[0] = IP_TAG_END;
ret = iprip_open(&conf);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipripd :: iprip_open() failed, err = %ld", ret);
goto badout;
}
iprip_open_ok = IP_TRUE;
/***** Start RIP on all external interfaces that are up. *****/
ifrs = ipcom_if_nameindex();
if (ifrs == IP_NULL)
{
IPCOM_LOG0(ERR, "ipripd :: ipcom_if_nameindex() failed");
goto badout;
}
for (oifrs = ifrs; ifrs && ifrs->if_name != IP_NULL; ifrs++)
{
/* Do not run RIP on loopback interface. */
if (ipcom_strcmp(ifrs->if_name, "lo0") == 0 || ipcom_strcmp(ifrs->if_name, "lo") == 0)
continue;
ripconf = iprip_ifgetconf(ifrs->if_name);
if (ripconf == IP_NULL || ipcom_strstr(ripconf, "ignore"))
continue;
ret = iprip_ifattach(ifrs->if_name, ripconf);
if (ret != IPCOM_SUCCESS) /*lint -e415 */
{
IPCOM_LOG2(ERR, "ipripd :: failed to attach RIP on %s : %s",
ifrs->if_name, ipcom_err_string(ret));
}
}
ipcom_if_freenameindex(oifrs);
/***** Add initial static RIP routes. *****/
for(num = 0; iprip_staticroute_config[num] != IP_NULL; num++)
{
const char *confstr;
ipcom_memset(&route, 0, sizeof(Iprip_route));
route.metric = 1;
IP_BIT_SET(route.flags, IPRIP_ROUTE_FLAG_STATIC);
for(confstr = iprip_staticroute_config[num];;)
{
confstr = iprip_ifgetconfopt(confstr, option);
if (confstr == IP_NULL)
break;
if (ipcom_strncmp(option, "dst=", 4) == 0)
route.ipaddr_n = (Ip_u32)ipcom_inet_addr(&option[4]);
else if (ipcom_strncmp(option, "mask=", 5) == 0)
route.mask_n = (Ip_u32)ipcom_inet_addr(&option[5]);
else if (ipcom_strncmp(option, "gw=", 3) == 0)
route.router_n = (Ip_u32)ipcom_inet_addr(&option[3]);
else if (ipcom_strncmp(option, "metric=", 7) == 0)
route.metric = ipcom_atoi(&option[7]);
}
if (iprip_rtadd(&route) == IPCOM_SUCCESS)
{
int i;
i = ipcom_sprintf(option, "%s",
ipcom_inet_ntop(IP_AF_INET, &route.ipaddr_n, iprip_dstr, 16));
i += ipcom_sprintf(option + i, "/%s",
ipcom_inet_ntop(IP_AF_INET, &route.mask_n, iprip_dstr, 16));
(void)ipcom_sprintf(option + i, " -> %s",
ipcom_inet_ntop(IP_AF_INET, &route.router_n, iprip_dstr, 16));
IPCOM_LOG1(INFO, "ipripd :: added static RIP route: %s", option);
}
}
/* IPD init. */
if (ipcom_ipd_init("iprip", IPCOM_SUCCESS, &ipd_fd) != IPCOM_SUCCESS)
goto badout;
/***** Input loop. *****/
max = IP_MAX(udp_fd, rt_fd);
max = IP_MAX(max, ipd_fd);
IP_FD_ZERO(&read_set);
for(;;)
{
input:
IP_FD_SET(udp_fd, &read_set);
IP_FD_SET(rt_fd, &read_set);
IP_FD_SET(ipd_fd, &read_set);
num = ipcom_socketselect(max + 1, &read_set, IP_NULL, IP_NULL, IP_NULL);
/* RIP input. */
if (num > 0 && IP_FD_ISSET(udp_fd, &read_set))
{
num--;
msghdr.msg_name = &addr;
msghdr.msg_namelen = sizeof(struct Ip_sockaddr_in);
iovec.iov_len = 1500;
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_control = membuf.control;
msghdr.msg_controllen = sizeof(membuf.control);
msghdr.msg_flags = 0;
length = ipcom_recvmsg(udp_fd, &msghdr, 0);
if (length > 0)
{
Ipcom_sock_packet sockpkt;
sockpkt.from.ipaddr_n = addr.sin_addr.s_addr;
sockpkt.from.ifindex = pktinfop->ipi_ifindex;
sockpkt.from.port_n = addr.sin_port;
sockpkt.buf = iovec.iov_base;
sockpkt.maxlen = 1500;
sockpkt.len = (Ip_size_t)length;
/* Pass packet to IPRIP for input parsing. */
ret = iprip_ifread((Ip_u32)pktinfop->ipi_ifindex, &sockpkt);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipripd :: iprip_ifread() failed, err = %ld", ret);
}
}
else if (length < 0)
{
int err;
Ip_socklen_t errlen = sizeof(int);
(void)ipcom_getsockopt(udp_fd, IP_SOL_SOCKET, IP_SO_ERROR, &err, &errlen);
}
}
/* Routing socket input. */
if (num > 0 && IP_FD_ISSET(rt_fd, &read_set))
{
num--;
length = ipcom_recv(rt_fd, (void *)&membuf.rtmsg_buf, sizeof(membuf), 0);
if (length < (Ip_ssize_t)sizeof(struct Ipnet_rt_msghdr))
{
IP_PANIC2();
continue;
}
/* Truncated. */
if (length < membuf.rtmsg.rtm_msglen)
{
if (membuf.rtmsg_buf.sin[0].sin_family == IP_AF_INET6)
continue;
IPCOM_LOG2(DEBUG, "ipripd :: truncated rtsock message %ld/%d", length, (int)membuf.rtmsg.rtm_msglen);
continue;
}
switch(membuf.rtmsg.rtm_type)
{
case IPNET_RTM_NEWADDR:
case IPNET_RTM_DELADDR:
/*
* org_offset = sizeof(struct Ipnet_ifa_msghdr);
* addrs = membuf.ifamsg.ifam_addrs;
*/
goto input;
case IPNET_RTM_IFINFO:
org_offset = sizeof(struct Ipnet_if_msghdr);
addrs = membuf.ifmsg.ifm_addrs;
break;
default:
/* Ignore our own route messages. */
if (membuf.rtmsg.rtm_pid == ipripd_pid)
goto input;
/* Ignore routes to loopback. */
if (membuf.rtmsg.rtm_index == IPNET_IF_LOOPBACK_INDEX)
goto input;
/* Ignore failed routes. */
if (membuf.rtmsg.rtm_errno != 0)
goto input;
org_offset = sizeof(struct Ipnet_rt_msghdr);
addrs = (int)membuf.rtmsg.rtm_addrs;
break;
}
cur_offset = org_offset;
sap_dst = sap_netmask = sap_ifa = (struct Ip_sockaddr *)IP_NULL;
/*sap_gateway = IP_NULL;*/
if (IP_BIT_ISSET(addrs, IPNET_RTA_DST))
{
sap_dst = (struct Ip_sockaddr *)&membuf.offset[cur_offset];
cur_offset += IPCOM_SA_LEN_GET(sap_dst);
/* Ignore all non IPv4 DST messages. */
if (sap_dst->sa_family != IP_AF_INET)
continue;
}
if (IP_BIT_ISSET(addrs, IPNET_RTA_GATEWAY))
{
sap_gateway = (struct Ip_sockaddr *)&membuf.offset[cur_offset];
cur_offset += IPCOM_SA_LEN_GET(sap_gateway);
}
if (IP_BIT_ISSET(addrs, IPNET_RTA_NETMASK))
{
sap_netmask = (struct Ip_sockaddr *)&membuf.offset[cur_offset];
cur_offset += IPCOM_SA_LEN_GET(sap_netmask);
}
if (IP_BIT_ISSET(addrs, IPNET_RTA_IFP))
{
sap_ifp = (struct Ip_sockaddr *)&membuf.offset[cur_offset];
cur_offset += IPCOM_SA_LEN_GET(sap_ifp);
}
if (IP_BIT_ISSET(addrs, IPNET_RTA_IFA))
{
sap_ifa = (struct Ip_sockaddr *)&membuf.offset[cur_offset];
/*cur_offset += sap_ifa->sa_len;*/
}
#if IPRIP_SYSLOG_PRIORITY >= IPCOM_LOG_DEBUG2
IPCOM_LOG4(DEBUG2, "ipripd :: [%ld] RTSOCK: %s, len: %d, %s",
ipcom_time(0) - start,
ipcom_cmd_key_to_str(iprip_rtm_map, membuf.rtmsg.rtm_type, buf, sizeof(buf)),
membuf.rtmsg.rtm_msglen,
membuf.rtmsg.rtm_type != IPNET_RTM_IFINFO ? "" :
IP_BIT_ISSET(membuf.ifmsg.ifm_flags, IP_IFF_UP) ? "UP" : "DOWN");
iprip_rtmsg_print_addresses(addrs, (struct Ip_sockaddr *)&membuf.offset[org_offset]);
#endif
switch(membuf.rtmsg.rtm_type)
{
case IPNET_RTM_ADD:
case IPNET_RTM_DELETE:
/* Prepare IPRIP route structure. */
ipcom_memset(&route, 0, sizeof(Iprip_route));
route.metric = (Ip_s32)membuf.rtmsg.rtm_rmx.rmx_hopcount;
IP_BIT_SET(route.flags, IPRIP_ROUTE_FLAG_LEAKED);
ip_assert(sap_dst != IP_NULL);
route.ipaddr_n = ((struct Ip_sockaddr_in *)sap_dst)->sin_addr.s_addr;
route.mask_n = sap_netmask ? ((struct Ip_sockaddr_in *)sap_netmask)->sin_addr.s_addr : 0xffffffff;
route.router_n = sap_ifa ? ((struct Ip_sockaddr_in *)sap_ifa)->sin_addr.s_addr : 0;
if (route.metric == 0)
{
route.metric = 1;
IPCOM_LOG1(DEBUG2, "ipripd :: adjusting 0 metric local leaked route: %s",
ipcom_inet_ntop(IP_AF_INET, &route.ipaddr_n, iprip_dstr, 16));
}
/* Add/delete leaked route. */
if (membuf.rtmsg.rtm_type == IPNET_RTM_ADD)
ret = iprip_rtadd(&route);
else
ret = iprip_rtdelete(&route);
if (ret == IPCOM_SUCCESS)
{
int i;
i = ipcom_sprintf(option, "%s",
ipcom_inet_ntop(IP_AF_INET, &route.ipaddr_n, iprip_dstr, 16));
i += ipcom_sprintf(option + i, "/%s",
ipcom_inet_ntop(IP_AF_INET, &route.mask_n, iprip_dstr, 16));
(void)ipcom_sprintf(option + i, " -> %s",
ipcom_inet_ntop(IP_AF_INET, &route.router_n, iprip_dstr, 16));
IPCOM_LOG2(DEBUG, "ipripd :: %s leaked RIP route: %s",
membuf.rtmsg.rtm_type == IPNET_RTM_ADD ? "added" : "deleted",
option);
}
break;
case IPNET_RTM_IFINFO:
{
char ifname[IP_IFNAMSIZ];
Ip_bool isopen;
if (ipcom_if_indextoname(membuf.ifmsg.ifm_index, ifname) == IP_NULL)
break;
isopen = iprip_ifisopen(membuf.ifmsg.ifm_index);
if (isopen)
{
if (IP_BIT_ISFALSE(membuf.ifmsg.ifm_flags, IP_IFF_UP))
{
if (iprip_ifdetach(ifname) != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipripd :: failed to detach RIP on %s", ifname);
}
}
}
else
{
if (IP_BIT_ISTRUE(membuf.ifmsg.ifm_flags, IP_IFF_UP))
{
ripconf = iprip_ifgetconf(ifname);
if (ripconf != IP_NULL)
{
ret = iprip_ifattach(ifname, ripconf);
if (ret != IPCOM_SUCCESS) /*lint -e415 */
{
IPCOM_LOG2(ERR, "ipripd :: failed to attach RIP on %s : %s",
ifname, ipcom_err_string(ret));
}
}
}
}
}
break;
default:
break;
}
}
/* IPD socket input. */
if (num > 0 && IP_FD_ISSET(ipd_fd, &read_set))
{
int event;
event = ipcom_ipd_input(ipd_fd);
switch(event)
{
case IPCOM_IPD_EVENT_RECONFIGURE:
IPCOM_LOG0(INFO, "received IPD reconfigure message");
iprip_config_read();
break;
case IPCOM_IPD_EVENT_KILL:
IPCOM_LOG0(INFO, "received IPD kill message");
goto badout;
default:
break;
}
}
}
badout:
if (ipd_fd == IP_INVALID_SOCKET)
(void)ipcom_ipd_init("iprip", IPCOM_ERR_FAILED, &ipd_fd);
if (iprip_open_ok)
(void)iprip_close();
if (iprip_init_ok)
(void)iprip_exit();
if (iovec.iov_base != IP_NULL)
ipcom_free(iovec.iov_base);
if (udp_fd != IP_INVALID_SOCKET)
ipcom_socketclose(udp_fd);
if (rt_fd != IP_INVALID_SOCKET)
ipcom_socketclose(rt_fd);
(void)ipcom_ipd_exit("iprip", ipd_fd);
IPCOM_LOG0(INFO, "ipripd :: ending");
ipcom_proc_exit();
}
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iprip_create
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
iprip_create(void)
{
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* iprip_start
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
iprip_start(void)
{
Ip_err ret;
Ipcom_proc_attr attr;
ipcom_proc_attr_init(&attr);
attr.priority = IPCOM_PRIORITY_DEFAULT - 1;
ret = ipcom_proc_acreate("ipripd", ipripd, &attr, IP_NULL);
ip_assert(ret == IPCOM_SUCCESS);
return ret;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,429 @@
/*
******************************************************************************
* INTERPEAK EXAMPLE SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iprip_util.c,v $ $Revision: 1.20.10.1 $
* $Source: /home/interpeak/CVSRoot/iprip/src/iprip_util.c,v $
* $Author: hxie $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "iprip_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_inet.h>
#include <ipcom_syslog.h>
#include <ipcom_shell.h>
#include <ipnet_config.h>
#include <ipnet.h>
#include <ipnet_routesock.h>
#include <ipnet_cmd.h>
#include "iprip.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* Syslog priority and facility. */
#if defined(_WRS_CONFIG_IPRIP_SYSLOG_PRIORITY)
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPRIP_SYSLOG_PRIORITY
#else
#define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_PRIO_DEFAULT
#endif
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPRIP
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
IP_EXTERN IP_CONST char *iprip_interface_config[];
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_GLOBAL char *iprip_ifgetconf(const char *ifname);
IP_GLOBAL const char *iprip_ifgetconfopt(const char *confstr, char *option);
IP_GLOBAL Ip_err iprip_ifattach(const char *ifname, const char *confstr);
IP_GLOBAL Ip_err iprip_ifdetach(const char *ifname);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* iprip_getconfopt
*===========================================================================
* Description: Get RIP configuration option.
* Parameters:
* Returns:
*
*/
IP_GLOBAL const char *
iprip_ifgetconfopt(const char *confstr, char *option)
{
int i;
ip_assert(option != IP_NULL);
option[0] = '\0';
if (confstr == IP_NULL || confstr[0] == '\0')
return IP_NULL;
ip_assert(confstr != IP_NULL);
for (i = 0; *confstr != '\0'; confstr++, i++)
{
if (*confstr == ' ')
{
confstr++;
break;
}
option[i] = *confstr;
}
option[i] = '\0';
return confstr;
}
/*
*===========================================================================
* iprip_ifgetconf
*===========================================================================
* Description: Get RIP configuration.
* Parameters: ifname - interface name.
* Returns: RIP configuration or IP_NULL if none (= don't run RIP).
*
*/
IP_GLOBAL char *
iprip_ifgetconf(const char *ifname)
{
int c;
char *best = IP_NULL;
for (c = 0; iprip_interface_config[c] != IP_NULL; c++)
{
if (ipcom_strncmp(iprip_interface_config[c], "all", 3) == 0)
best = (char *)iprip_interface_config[c];
if (ipcom_strncmp(iprip_interface_config[c], ifname, ipcom_strlen(ifname)) == 0)
return (char *)iprip_interface_config[c];
}
return best;
}
/*
*===========================================================================
* iprip_ifattach
*===========================================================================
* Description: Ready-to-use function to attach RIP on an interface.
* Parameters: ifname - interface name.
* confstr - configuration string.
* Returns: IPCOM_SUCCESS or IPCOM_ERR_XXX.
*
*/
IP_GLOBAL Ip_err
iprip_ifattach(const char *ifname, const char *confstr)
{
Iprip_interface *ift;
struct Ip_sockaddr_in *addrp;
struct Ip_ifreq ifr;
int i = 0, j;
Ip_u32 ifindex;
Ip_fd fd;
Ip_err retval = IPCOM_ERR_FAILED;
char option[64];
Ip_bool multicast = IP_FALSE;
if (confstr == IP_NULL)
return IPCOM_ERR_INVALID_ARG;
ipcom_strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
ifindex = ipcom_if_nametoindex(ifname);
if (ifindex == 0)
return IPCOM_ERR_INVALID_INTERFACE;
fd = iprip_socket();
if (fd == IP_INVALID_SOCKET)
return IPCOM_ERR_NOT_OPENED;
/* Allocate space for up to 8 optional tags (8*(sizeof(Ip_tag)*2)). */
ift = (Iprip_interface *)ipcom_malloc(sizeof(Iprip_interface) + 8*2*sizeof(Ip_tag));
if (ift == IP_NULL)
goto badout;
memset(ift, 0x00, sizeof(Iprip_interface) + 8*2*sizeof(Ip_tag));
/* 1) Common configuration. */
/* 1a) Get IP address. */
if (ipcom_socketioctl(fd, IP_SIOCGIFADDR, &ifr) != IP_SOCKERR)
{
addrp = (struct Ip_sockaddr_in *)&ifr.ip_ifr_addr;
ift->ipaddr_n = (Ip_u32)addrp->sin_addr.s_addr;
}
else
goto badout;
/* 1b) Get subnet mask. */
if (ipcom_socketioctl(fd, IP_SIOCGIFNETMASK, &ifr) != IP_SOCKERR)
{
addrp = (struct Ip_sockaddr_in *)&ifr.ip_ifr_addr;
ift->mask_n = addrp->sin_addr.s_addr;
}
else
goto badout;
/* 1c) Foreign address for PPP interfaces. */
if (ipcom_socketioctl(fd, IP_SIOCGIFFLAGS, &ifr) != IP_SOCKERR)
{
/* While at it, check if interface is really up. */
if (!IP_BIT_ISSET(ifr.ip_ifr_flags, IP_IFF_UP))
goto badout;
/* Get foreign IP address. */
if (IP_BIT_ISSET(ifr.ip_ifr_flags, IP_IFF_POINTOPOINT))
{
if (ipcom_socketioctl(fd, IP_SIOCGIFDSTADDR, &ifr) != IP_SOCKERR)
{
addrp = (struct Ip_sockaddr_in *)&ifr.ip_ifr_addr;
ift->conf[i++] = IPTAG_IPRIP_FOREIGN_IPADDR;
ift->conf[i++] = (Ip_tag)addrp->sin_addr.s_addr; /*lint !e415 */
}
}
}
/* Configuration options. */
for (;;)
{
confstr = iprip_ifgetconfopt(confstr, option);
if (confstr == IP_NULL)
break;
if (ipcom_strcmp(option, "broadcast") == 0)
{
if (ipcom_socketioctl(fd, IP_SIOCGIFBRDADDR, &ifr) != IP_SOCKERR)
{
addrp = (struct Ip_sockaddr_in *)&ifr.ip_ifr_addr;
ift->brdaddr_n = addrp->sin_addr.s_addr;
}
else
{
retval = IPCOM_ERR_SOCKCALLFAILED;
goto badout;
}
}
else if (ipcom_strcmp(option, "multicast") == 0 || ipcom_strcmp(option, "input-multicast") == 0)
{
struct Ip_ip_mreq mreq;
if (ipcom_strcmp(option, "multicast") == 0)
ift->brdaddr_n = IPRIP_MADDR;
/* Enable receival of multicast packets on this interface. */
if (multicast == IP_FALSE)
{
mreq.imr_multiaddr.s_addr = IPRIP_MADDR;
mreq.imr_interface.s_addr = ift->ipaddr_n;
if (ipcom_setsockopt(fd, IP_IPPROTO_IP, IP_IP_JOIN_GROUP, &mreq, sizeof(mreq)) == IP_SOCKERR)
{
if (ipcom_errno != IP_ERRNO_EADDRINUSE)
{
/* Allow EADDRINUSE since it may happen if detach was called. */
retval = IPCOM_ERR_SOCKCALLFAILED;
goto badout;
}
}
multicast = IP_TRUE;
}
}
else if (ipcom_strncmp(option, "auth-", 5) == 0)
{
j = 5;
ift->conf[i++] = IPTAG_IPRIP_AUTH_TYPE;
if (ipcom_strncmp(&option[j], "simple=", 7) == 0)
{
ift->conf[i++] = IPRIP_AUTHTYPE_SIMPLE;
j += 7;
}
else if (ipcom_strncmp(&option[j], "md5=", 4) == 0)
{
ift->conf[i++] = IPRIP_AUTHTYPE_MD5;
j += 4;
}
else
{
retval = IPCOM_ERR_INVALID_CONFIG;
goto badout;
}
ift->conf[i++] = IPTAG_IPRIP_AUTH_PASSWORD;
ift->conf[i++] = (Ip_tag)&option[j];
}
else if (ipcom_strncmp(option, "input=", 6) == 0)
{
j = 6;
ift->conf[i++] = IPTAG_IPRIP_RX_COMPAT;
if (ipcom_strcmp(&option[j], "no") == 0)
ift->conf[i++] = IPRIP_RX_RIPX_NONE;
else if (ipcom_strcmp(&option[j], "v1") == 0)
ift->conf[i++] = IPRIP_RX_RIP1_ONLY;
else if (ipcom_strcmp(&option[j], "v2") == 0)
ift->conf[i++] = IPRIP_RX_RIP2_ONLY;
else
ift->conf[i++] = IPRIP_RX_RIPX_ANY;
}
else if (ipcom_strncmp(option, "metric=", 7) == 0)
{
ift->conf[i++] = IPTAG_IPRIP_METRIC;
ift->conf[i++] = (Ip_tag)ipcom_atoi(&option[7]);
}
else if (ipcom_strcmp(option, "version-1") == 0)
{
ift->conf[i++] = IPTAG_IPRIP_VERSION;
ift->conf[i++] = 1;
}
else if (ipcom_strcmp(option, "silent") == 0)
{
ift->brdaddr_n = 0;
}
else if (ipcom_strcmp(option, "nopoison") == 0)
{
ift->conf[i++] = IPTAG_IPRIP_DISABLE_POISON;
ift->conf[i++] = 1;
}
} /* for (;;) */
/* 2) Optional configuration, tags. */
/* Mandatory TAG terminator. */
ift->conf[i] = IP_TAG_END;
ipcom_bufcheck(ift);
/* Open RIP on this interface. */
retval = iprip_ifopen(ifindex, ift);
if (retval != IPCOM_SUCCESS)
goto badout;
/* Success */
IPCOM_LOG1(INFO, "attached RIP on interface %s.", ifname);
retval = IPCOM_SUCCESS;
/* Failure */
badout:
if (ift != IP_NULL)
ipcom_free(ift);
return retval;
}
/*
*===========================================================================
* iprip_ifdetach
*===========================================================================
* Description: Detach RIP on an interface.
* Parameters: ifname - RIP interface name to detach.
* Returns: IPCOM_SUCCESS or IPCOM_ERR_XX.
*
*/
IP_GLOBAL Ip_err
iprip_ifdetach(const char *ifname)
{
Ip_u32 ifindex;
/* Get interface index from interface name. */
ifindex = ipcom_if_nametoindex(ifname);
if (ifindex == 0)
return IPCOM_ERR_INVALID_INTERFACE;
IPCOM_LOG1(INFO, "detaching RIP on interface %s.", ifname);
/* Closing RIP on this interface. */
return iprip_ifclose(ifindex);
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/