Files
m241Neelima/components/ip_net2-6.9/vxcompat/src/ifLib.c
T
2026-07-30 11:19:44 +05:30

1641 lines
42 KiB
C

/* ifLib.c - network interface library */
/*
* Copyright (c) 1984-2005, 2007-2008 Wind River Systems, Inc.
*
* The right to copy, distribute or otherwise make use of this software
* may be licensed only pursuant to the terms of an applicable Wind River
* license agreement. No license to Wind River intellectual property rights
* is granted herein. All rights not licensed by Wind River are reserved
* by Wind River.
*/
#include "copyright_wrs.h"
/*
modification history
--------------------
02f,28dec11,h_x Fix WIND00253934
02e,29sep10,h_x Fix build and coverity warnings
02d,13apr10,h_x Fix WIND00203571
02c,20mar09,ggz Add INCLUDE_IPWRAP_IFLIB to the description.
02b,07nov08,brg Add arpResolve in ifLib for now.
02a,21oct08,spw Fix memory leak
01z,09sep08,spw ifMaskSet / ifAddrSet changes.
01y,30jun08,spw Reenable call to SIOCSIFBRDADDR
01x,15Nov07,brg Reinstated after "ipnetifing" the old version.
01w,14dec05,dlk In routeNodeDelete(), do not attempt to reset TOS information
if reference count is such that route entry would have been
deleted in RTM_DELETE request. (SPR #115159)
01v,18mar05,niq Don't try to delete non-existent route (SPR #106227)
01u,15mar05,niq Fix compilation error with -DDEBUG defined (SPR #106270)
01t,24feb05,spm code cleanup: removed unused table walk feature (SPR #100995)
01s,12jan05,vvv osdep.h cleanup
01r,09nov04,rae doc fixup
01q,30aug04,vvv fixed Diab warnings
01p,24aug04,niq unified stack merge
01o,12aug04,niq Fix inconsistent behavior for ifMaskSet and ifconfig: SPR 87094
01n,09jun04,spm removed duplicate address search from ifRouteDelete()
01m,21may04,vvv fixed ifBroadcastSet() to accept 255.255.255.255 (SPR #94785)
01l,17may04,vvv fixed docs (SPR #84776)
01k,16dec03,ijm merged SPR #85896,interface based proxy ARP services
01j,20nov03,niq osdep.h cleanup
01i,06nov03,rlm Ran batch header update for header re-org.
01h,08sep03,vvv merged from ACCORDION_BASE6_MERGE_BASELINE
01g,02may03,ijm added ifAddrDelete, added bzero to ifIoctlSet,ifIoctlGet
01f,01may03,spm Tornado 2.2 CP1 merge (from ver 03j,17jan03,vvv:
TOR2_2-CP1-F label, tor2_2-patch branch, /wind/river VOB)
01e,11apr03,ijm fixed diab compiler warnings
01d,07mar03,pas fixed some of the refgen comments
01c,01feb03,pas added hostLib.h and routeCmd.h to resolve compiler warnings
01b,06mar02,ham added ifLibInit
01a,02feb02,ppp ported from A.E. 1.1
*/
/*
DESCRIPTION
This library contains routines to configure the network interface parameters.
Generally, each routine corresponds to one of the functions of the UNIX
command 'ifconfig'.
To use this feature, include the component INCLUDE_IPWRAP_IFLIB.
INCLUDE FILES: ifLib.h
SEE ALSO: hostLib
*/
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#include <errnoLib.h>
#include <hostLib.h>
#include <ifLib.h>
#include <inetLib.h>
#include <logLib.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <sockLib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifndef _WRS_KERNEL
#include <sys/sysctl.h>
#endif
/* ipcom specific stuff */
#include <ipcom_clib.h>
#include <ipcom_cstyle.h>
#include <ipcom_err.h>
#include <ipcom_sock2.h>
#include <ipcom_sysctl.h>
#include <ipcom_sysvar.h>
#include <ipcom_type.h>
#include <ipcom_vxworks.h>
#include <ipnet.h>
#include <ipnet.h>
#include <ipnet_h.h>
#include <ipnet_route.h>
/* Needed for arpResolve */
#include <ipnet_eth.h>
#include <ipnet_ip4.h>
/*
****************************************************************************
* TYPES
****************************************************************************
*/
typedef struct ifLib_route_cb_data_t
{
Ipnet_netif *netif; /* pointer to the interface */
Ip_u32 addr; /* route to search for */
Ip_u32 count; /* route count */
} ifLib_route_cb_data;
/*
****************************************************************************
* LOCAL PROTOTYPES
****************************************************************************
*/
LOCAL Ip_bool ifAllRoutesDeleteCallback (Ipnet_route_entry *rt, ifLib_route_cb_data *cb_data);
LOCAL Ip_bool ifRouteDeleteCallback (Ipnet_route_entry *rt, ifLib_route_cb_data *cb_data);
LOCAL Ip_err ipcom_proxy_sys_var(char *interfaceName,char* enable);
int ifRouteDelete(char *ifName,int unit);
/*******************************************************************************
*
* ifLibInit - Initialize ifLib
*
* RETURNS: N/A
*
* NOMANUAL
*/
void ifLibInit (void)
{
return;
}
/*******************************************************************************
*
* ifIoctlCall - make ioctl call to socket layer
*
* ifIoctlCall creates a dummy socket to get access to the socket layer
* ioctl routines in order to manipulate the interface specific
* configurations.
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS ifIoctlCall
(
int code, /* ioctl code */
struct ifreq *ifrp /* pointer to the interface ioctl request */
)
{
int sock;
int status;
if ((sock = socket (AF_INET, SOCK_RAW, 0)) < 0)
return (ERROR);
status = ioctl (sock, code, (long)ifrp);
(void)close (sock);
if (status != 0)
{
if (status != ERROR) /* iosIoctl() can return ERROR */
(void)errnoSet (status);
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* ifIoctlSet - configure network interface
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS ifIoctlSet
(
char *interfaceName, /* name of the network interface, i.e. ei0 */
int code, /* network interface ioctl function code */
int val /* value to be changed */
)
{
struct ifreq ifr;
bzero ((caddr_t) &ifr, sizeof (ifr));
strncpy (ifr.ifr_name, interfaceName, sizeof (ifr.ifr_name));
ifr.ifr_name[IFNAMSIZ-1] = 0;
switch ((UINT) code)
{
case SIOCSIFFLAGS:
ifr.ifr_flags = (u_short)val;
break;
case SIOCSIFMETRIC:
ifr.ifr_metric = val;
break;
default:
ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in);
ifr.ifr_addr.sa_family = AF_INET;
((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = (in_addr_t)val;
break;
}
return (ifIoctlCall (code, &ifr));
}
/*******************************************************************************
*
* ifIoctlGet - retrieve information about the network interface
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS ifIoctlGet
(
char *interfaceName, /* name of the network interface, i.e. ei0 */
int code, /* network interface ioctl function code */
int *val /* where to return result */
)
{
struct ifreq ifr;
bzero ((caddr_t) &ifr, sizeof (ifr));
strncpy (ifr.ifr_name, interfaceName, (sizeof(ifr.ifr_name)-1));
ifr.ifr_name[IFNAMSIZ-1] = 0;
if (ifIoctlCall (code, &ifr) == ERROR)
return (ERROR);
switch ((UINT) code)
{
case SIOCGIFFLAGS:
*val = ifr.ifr_flags;
break;
case SIOCGIFMETRIC:
*val = ifr.ifr_metric;
break;
default:
*val = (int)(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr);
break;
}
return (OK);
}
/*******************************************************************************
*
* ifIoctl - network interface ioctl front-end
*
* Used to manipulate the characteristics of network interfaces
* using socket specific ioctl functions SIOCSIFADDR, SIOCSIFBRDADDR, etc.
* ifIoctl() accomplishes this by calling ifIoctlSet() and ifIoctlGet().
*
* RETURNS: OK or ERROR
*
* ERRNO: EOPNOTSUPP
*/
LOCAL STATUS ifIoctl
(
char *interfaceName, /* name of the interface, i.e. ei0 */
int code, /* ioctl function code */
_Vx_usr_arg_t arg /* some argument */
)
{
int status;
int hostAddr;
switch ((UINT) code)
{
case SIOCSIFBRDADDR:
if (strcmp ((char *) arg, "255.255.255.255") == 0)
{
status = ifIoctlSet (interfaceName, code, (int)0xffffffff);
break;
}
case SIOCAIFADDR:
case SIOCDIFADDR:
case SIOCSIFADDR:
case SIOCSIFDSTADDR:
if ((hostAddr = (int) inet_addr ((char *)arg)) == ERROR &&
(hostAddr = hostGetByName ((char *)arg)) == ERROR)
{
return (ERROR);
}
status = ifIoctlSet (interfaceName, code, hostAddr);
break;
case SIOCSIFNETMASK:
case SIOCSIFFLAGS:
case SIOCSIFMETRIC:
status = ifIoctlSet (interfaceName, code, (int)arg);
break;
case SIOCGIFNETMASK:
case SIOCGIFFLAGS:
case SIOCGIFADDR:
case SIOCGIFBRDADDR:
case SIOCGIFDSTADDR:
case SIOCGIFMETRIC:
status = ifIoctlGet (interfaceName, code, (int *)arg);
break;
default:
(void)errnoSet (EOPNOTSUPP); /* not supported operation */
status = ERROR;
break;
}
return (status);
}
/*******************************************************************************
*
* ifAddrParamGet - call ifIoctl to get the Internet address of the interface
*
* ifAddrParamGet may be used to retrieve Internet address of the network
* interface in ASCII character string representation (dot-notation
* like "192.0.0.3").
*
* RETURNS: OK or ERROR
*
* ERRNO: EINVAL
*
* SEE ALSO: ifAddrGet (), ifDstAddrGet (), ifBroadcastGet ()
*/
LOCAL STATUS ifAddrParamGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int code, /* SIOCG ioctl code */
char *address /* address retrieved here */
)
{
struct in_addr inetAddrBuf; /* result */
char netString [INET_ADDR_LEN];
if (address == NULL)
{
(void)errnoSet (EINVAL);
return (ERROR);
}
if (ifIoctl (interfaceName, code, (_Vx_usr_arg_t)&inetAddrBuf) == OK)
{
inet_ntoa_b (inetAddrBuf, netString);
strncpy (address, netString, INET_ADDR_LEN);
return (OK);
}
return (ERROR);
}
/* End of utility functions */
/*******************************************************************************
*
* ifAddrGet - get the Internet address of a network interface
*
* This routine gets the Internet address of a specified network interface and
* copies it to <interfaceAddress>. This pointer should point to a buffer
* large enough to contain INET_ADDR_LEN bytes.
*
* \is
* \i <interfaceName>
* The name for the interface.
* \i <interfaceAddress>
* The location where the interface address is copied
* \ie
*
* EXAMPLE
* .CS
* char * interfaceAddress;
* interfaceAddress = malloc(INET_ADDR_LEN);
* ifAddrGet ("mottsec0", interfaceAddress);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrAdd(), ifAddrSet()
*/
STATUS ifAddrGet(
char *interfaceName,
char *interfaceAddress
)
{
return ifAddrParamGet(interfaceName,(int)SIOCGIFADDR,interfaceAddress);
}
/*******************************************************************************
*
* ifAddrAdd - Add an interface address for a network interface
*
* This routine assigns an Internet address to a specified network interface.
* The Internet address can be a host name or a standard Internet address
* format (e.g., 90.0.0.4). If a host name is specified, it should already
* have been added to the host table with hostAdd().
*
* You must specify both an <interfaceName> and an <interfaceAddress>. A
* <broadcastAddress> is not used, but retained for compatibility. The IPNET stack
* generates a <broadcastAddress> value based on the <interfaceAddress> value
* and the netmask. A <subnetMask> value is optional. If <subnetMask> is 0,
* the stack uses a <subnetMask> the same as the netmask that is generated
* by the <interfaceAddress>.
*
* \is
* \i <interfaceName>
* The name for the interface.
* \i <interfaceAddress>
* The interface address.
* \i <broadcastAddress>
* broadcast address.
* \i <subnetMask>
* Optional subnet mask.
* \ie
*
* EXAMPLE
* .CS
* ifAddrAdd ("mottsec0", "90.0.0.4", NULL, NULL);
* .CE
*
* RETURNS: OK, or ERROR if the interface cannot be set.
*
* SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet() ifBroadcastSet()
*/
STATUS ifAddrAdd
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *interfaceAddress, /* IPv4 Address to be added to interface */
char *broadcastAddress, /* Dummy */
int subnetMask /* Optional subnet mask */
)
{
struct ifaliasreq ifa;
struct sockaddr_in *pSin_iaddr = (struct sockaddr_in *)&ifa.ifra_addr;
struct sockaddr_in *pSin_baddr = (struct sockaddr_in *)&ifa.ifra_broadaddr;
struct sockaddr_in *pSin_snmsk = (struct sockaddr_in *)&ifa.ifra_mask;
bzero ((caddr_t) &ifa, sizeof (ifa));
/* verify Internet address is in correct format */
if(inet_addr(interfaceAddress) == (uint32_t)ERROR)
{
if(hostGetByName(interfaceAddress) == (long)ERROR)
{
return (ERROR);
}
else
{
pSin_iaddr->sin_addr.s_addr = (in_addr_t)(hostGetByName(interfaceAddress));
}
}
else
{
pSin_iaddr->sin_addr.s_addr = (in_addr_t)(inet_addr(interfaceAddress));
}
/* verify broadcast address is in correct format */
if(broadcastAddress != NULL)
{
if(inet_addr(broadcastAddress) == (uint32_t)ERROR)
{
if(hostGetByName(broadcastAddress) == (long)ERROR)
{
return (ERROR);
}
else
{
pSin_baddr->sin_addr.s_addr = (in_addr_t)(hostGetByName(broadcastAddress));
}
}
else
{
pSin_baddr->sin_addr.s_addr = (in_addr_t)(inet_addr(broadcastAddress));
}
}
strncpy (ifa.ifra_name, interfaceName, (sizeof(ifa.ifra_name)-1));
ifa.ifra_name[IFNAMSIZ-1] = 0;
/* for interfaceAddress */
ifa.ifra_addr.sa_len = sizeof (struct sockaddr_in);
ifa.ifra_addr.sa_family = AF_INET;
/* for broadcastAddress */
/* IPNET doesnt make use of this structure member */
if (broadcastAddress != NULL)
{
ifa.ifra_broadaddr.sa_len = sizeof (struct sockaddr_in);
ifa.ifra_broadaddr.sa_family = AF_INET;
}
/* for subnetmask */
if (subnetMask != 0)
{
ifa.ifra_mask.sa_len = sizeof (struct sockaddr_in);
ifa.ifra_mask.sa_family = AF_INET;
pSin_snmsk->sin_addr.s_addr = htonl (subnetMask);
}
return (ifIoctlCall ((int)SIOCAIFADDR, (struct ifreq *) &ifa));
}
/*******************************************************************************
*
* ifAddrDelete - delete an interface address for a network interface
*
* This routine deletes an Internet address from a specified network interface.
* The Internet address can be a host name or a standard Internet address
* format (e.g., 90.0.0.4). If a host name is specified, it should already
* have been added to the host table with hostAdd().
*
* \is
* \i <interfaceName>
* The name for the interface.
* \i <interfaceAddress>
* Interface IP address.
* \ie
*
* EXAMPLE
* .CS
* ifAddrDelete ("mottsec0", "90.0.0.4");
* .CE
*
* NOTE
* This function only works for address family AF_INET.
* RETURNS: OK, or ERROR if the interface address cannot be deleted.
*
* SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet()
*/
STATUS ifAddrDelete
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *interfaceAddress /* IPv4 Address to be deleted from the interface */
)
{
return (ifIoctl (interfaceName, (int)SIOCDIFADDR, (_Vx_usr_arg_t)interfaceAddress));
}
/*******************************************************************************
*
* ifAddrSet - set an interface address for a network interface
*
* This routine assigns an Internet address to a specified network interface.
* The Internet address can be a host name or a standard Internet address
* format (e.g., 90.0.0.4). If a host name is specified, it should already
* have been added to the host table with hostAdd().
*
* A successful call to ifAddrSet() results in the addition of a new route.
*
* The subnet mask used in determining the network portion of the address will
* be that set by ifMaskSet(), or the default class mask if ifMaskSet() has not
* been called. It is standard practice to call ifAddrSet() prior to calling
* ifMaskSet().
*
* \is
* \i <interfaceName>
* The name for the interface.
* \i <interfaceAddress>
* Interface IP address.
* \ie
*
* EXAMPLE
* .CS
* ifAddrSet ("mottsec0", "90.0.0.4");
* .CE
*
* RETURNS: OK, or ERROR if the interface cannot be set.
*
* SEE ALSO: ifAddrGet(), ifDstAddrSet(), ifDstAddrGet()
*/
STATUS ifAddrSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *interfaceAddress /* IPv4 Address to be assigned */
)
{
int argc;
char * tempArgv[3];
char ** argv = tempArgv;
int hostAddr;
char hostaddr[32];
int errCode = 0;
if (interfaceName == NULL || interfaceAddress == NULL)
{
return ERROR;
}
if ((hostAddr = (int)inet_addr(interfaceAddress)) == ERROR &&
(hostAddr = hostGetByName(interfaceAddress)) == ERROR)
{
return (ERROR);
}
inet_ntop(AF_INET, &hostAddr, hostaddr, 32);
argv[0] = "ifconfig";
argv[1] = interfaceName;
argv[2] = hostaddr;
argc = 3;
if ((errCode = ipnet_cmd_ifconfig_common (argc, argv)) == IPCOM_SUCCESS)
{
return OK;
}
errCode = IPCOM_ERRNO(errCode);
if (errCode)
errnoSet (errCode);
return ERROR;
}
/*******************************************************************************
*
* ifBroadcastSet - set the broadcast address for a network interface
*
* This routine assigns a broadcast address for the specified network interface.
* The broadcast address must be a string in standard Internet address format
* (e.g., 90.0.0.0).
*
* An interface's default broadcast address is its Internet address with a
* host part of all ones (e.g., 90.255.255.255). This conforms to current
* ARPA specifications. However, some older systems use an Internet address
* with a host part of all zeros as the broadcast address. The default
* broadcast address is always set when the interface address is added.
*
* NOTE
* If VxWorks is to broadcast to older systems using a host part of all zeros
* as the broadcast address, this routine should be used to change the
* broadcast address of the interface.
*
* \is
* \i <interfaceName>
* The name for the interface.
* \i <broadcastAddress>
* Interface broadcast address.
* \ie
*
* EXAMPLE
* .CS
* ifBroadcastSet ("mottsec0", "90.255.255.255");
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrSet(), ifBroadcastGet()
*/
STATUS ifBroadcastSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *broadcastAddress /* Broadcast address to be set */
)
{
return (ifIoctl (interfaceName, (int)SIOCSIFBRDADDR,
(_Vx_usr_arg_t)broadcastAddress));
}
/*******************************************************************************
*
* ifBroadcastGet - get the broadcast address for a network interface
*
* This routine gets the broadcast address for a specified network interface.
* The broadcast address is copied to the buffer <broadcastAddress>.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <broadcastAddress>
* The location where the interface broadcast address is copied
* \ie
*
* EXAMPLE
* .CS
* char * broadcastAddress;
* broadcastAddress = malloc(INET_ADDR_LEN);
* ifBroadcastGet ("mottsec0", broadcastAddress);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrGet(), ifBroadcastSet()
*/
STATUS ifBroadcastGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *broadcastAddress /* Buffer for broadcast address */
)
{
return ifAddrParamGet(interfaceName,(int)SIOCGIFBRDADDR,broadcastAddress);
}
/*******************************************************************************
*
* ifDstAddrGet - get the Internet address of a point-to-point peer
*
* This routine gets the Internet address of a machine connected to the
* opposite end of a point-to-point network connection. The Internet address is
* copied to the buffer <dstAddress>.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <dstAddress>
* The location where the destination address is copied
* \ie
*
* EXAMPLE
* .CS
* char * dstAddress;
* dstAddress = malloc(INET_ADDR_LEN);
* ifDstAddrGet ("mottsec0", dstAddress);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrGet(), ifDstAddrSet()
*/
STATUS ifDstAddrGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *dstAddress /* buffer for destination address. */
)
{
return ifAddrParamGet(interfaceName,(int)SIOCGIFDSTADDR,dstAddress);
}
/*******************************************************************************
*
* ifDstAddrSet - define an address for the other end of a point-to-point link
*
* This routine assigns the Internet address of a machine connected to the
* opposite end of a point-to-point network connection, such as a SLIP
* connection. Inherently, point-to-point connection-oriented protocols such as
* SLIP require that addresses for both ends of a connection be specified.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <dstAddress>
* define an address for the other end of a point-to-point link.
* \ie
*
* EXAMPLE
* .CS
* ifDstAddrSet ("mottsec0", "90.0.0.4");
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrSet(), ifDstAddrGet()
*/
STATUS ifDstAddrSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char *dstAddress /* P2P link destination address to be set */
)
{
return (ifIoctl (interfaceName, (int)SIOCSIFDSTADDR, (_Vx_usr_arg_t)dstAddress));
}
/*******************************************************************************
*
* ifMaskSet - define a subnet for a network interface
*
* This routine allocates additional bits to the network portion of an
* Internet address. The network portion is specified with a mask that must
* contain ones in all positions that are to be interpreted as the network
* portion. This includes all the bits that are normally interpreted as the
* network portion for the given class of address, plus the bits to be added.
* Note that all bits must be contiguous. The mask is specified in host byte
* order.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <netMask>
* Net Mask.
* \ie
*
* EXAMPLE
* .CS
* ifMaskSet ("mottsec0", 0xffffff00);
* .CE
*
* NOTE: A subnet mask SHOULD be set for an interface after setting the Internet
* address of the interface with the routine ifAddrSet(). If ifAddrSet() is not
* called prior to ifMaskSet, a transition address will be set on the 0.0.0.0/8
* network according to RFC 1700.
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrSet(), ifMaskGet()
*/
STATUS ifMaskSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int netMask /* subnet mask to be set */
)
{
char addr[INET_ADDR_LEN];
if (netMask == 0)
return ERROR;
/*
* If the interface doesn't have an address set already, we need to add a
* transition address in order to satisfy stack requirements for setting
* the mask on an interface. As such, ifMaskSet() should be followed
* immediately by a call to ifAddrSet or equivalent function call to set
* the actual address.
*/
if (ifAddrParamGet (interfaceName, (int)SIOCGIFADDR, addr) == ERROR)
{
if (ifAddrSet(interfaceName,"0.0.0.255") == ERROR)
{
return ERROR;
}
return (ifIoctl (interfaceName, (int)SIOCSIFNETMASK, (_Vx_usr_arg_t)(htonl(netMask))));
}
else
return (ifAddrAdd (interfaceName, addr, NULL, netMask));
}
/*******************************************************************************
*
* ifMaskGet - get the subnet mask for a network interface
*
* This routine gets the subnet mask for a specified network interface.
* The subnet mask is copied to the buffer <netMask>. The subnet mask is
* returned in host byte order.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <netMask>
* The location where the interface net mask is copied.
* \ie
*
* EXAMPLE
* .CS
* char * netMask;
* netMask = malloc(INET_ADDR_LEN);
* ifMaskGet ("mottsec0", netMask);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifAddrGet(), ifMaskSet()
*/
STATUS ifMaskGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int *netMask /* buffer for subnet mask */
)
{
int status = ifIoctl (interfaceName, (int)SIOCGIFNETMASK, (_Vx_usr_arg_t)netMask);
if (status != ERROR)
{
*netMask = (int)(ntohl(*netMask));
return OK;
}
return ERROR;
}
/*******************************************************************************
* ifFlagSet - specify the flags for a network interface
*
* This routine changes the flags for a specified network interface.
* Any combination of the following flags can be specified:
* \is
* \i IFF_UP (0x01)
* Brings the interface up or down.
* \i IFF_NOARP (0x80)
* Set to prevent external IP address/link layer translation (disables
* ARP or NDP for the interface).
* \i IFF_PROMISC (0x100)
* Identifies an itnerface that receives all packets.
* \ie
*
* NOTE
* The following flags can only be set at interface initialization time.
* Specifying these flags does not change any settings in the interface
* data structure.
* \is
* \i IFF_BROADCAST (0x2)
* Identifies a broadcast interface.
* \i IFF_LOOPBACK (0x08)
* Identifies a Loopback net.
* \i IFF_POINTOPOINT (0x10)
* Identifies a point-to-point interface such as PPP or SLIP.
* \i IFF_RUNNING (0x40)
* Set when the device turns on.
* \i IFF_SIMPLEX (0x800)
* Indicates whether interface receives own broadcasts.
* \i IFF_MULTICAST (0x8000)
* Indicates whether interface supports multicast traffic.
* \ie
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <flags>
* Interface flags to be set.
* \ie
*
* EXAMPLE
* .CS
* int flags;
* flags = | IFF_RUNNING;
* ifFlagSet ("mottsec0", flags);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifFlagChange(), ifFlagGet()
*/
STATUS ifFlagSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int flags /* interface flags to be set */
)
{
return (ifIoctl (interfaceName, (int)SIOCSIFFLAGS, (_Vx_usr_arg_t)flags));
}
/*******************************************************************************
*
* ifFlagGet - get the network interface flags
*
* This routine gets the flags for a specified network interface.
* The flags are copied to the buffer <flags>.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <flags>
* Interface flags to be set.
* \ie
*
* EXAMPLE
* .CS
* int flags;
* ifFlagGet ("mottsec0", &flags);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifFlagSet()
*/
STATUS ifFlagGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int *flags /* buffer for interface flags */
)
{
/* Warning for 64 bit! */
return ifIoctl (interfaceName, (int)SIOCGIFFLAGS, (_Vx_usr_arg_t)flags);
}
#ifndef IFF_INET6_UP
/* Should be defined in <net/if.h> */
#define IFF_INET6_UP 0x80000
#endif
/*******************************************************************************
*
* ifFlagChange - change the network interface flags
*
* This routine changes the flags for the specified network interfaces. If
* the parameter <on> is TRUE, the specified flags are turned on; otherwise,
* they are turned off. The routines ifFlagGet() and ifFlagSet() are called
* to do the actual work.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <flags>
* Interface flags to be changed.
* \ie
*
* EXAMPLE
* .CS
* int flags;
* flags = | IFF_RUNNING;
* ifFlagChange ("mottsec0", flags, TRUE); /@ the interface flags will change to be IFF_RUNNING @/
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifFlagGet(), ifFlagSet()
*/
STATUS ifFlagChange
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int flags, /* flags to be changed */
BOOL on /* TRUE for on and FALSE for off */
)
{
int oldFlags;
if (flags & IFF_INET6_UP)
{
int name[5];
name[0] = IP_CTL_NET;
name[1] = IP_AF_INET6;
name[2] = IP_IPPROTO_IPV6;
name[3] = IP_IPV6CTL_ENABLED;
name[4] = (int)ipcom_if_nametoindex(interfaceName);
if (name[4] == 0)
return ERROR;
if (ipcom_sysctl(name, 5, IP_NULL, IP_NULL, &on, sizeof(on)) < 0)
return ERROR;
flags &= ~IFF_INET6_UP;
}
if (ifFlagGet (interfaceName, &oldFlags) == ERROR)
{
return (ERROR);
}
if (on)
oldFlags |= flags;
else
oldFlags &= ~flags;
return (ifFlagSet (interfaceName, oldFlags));
}
/*******************************************************************************
*
* ifMetricSet - specify a network interface hop count
*
* This routine configures <metric> for a network interface from the host.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <metric>
* Interface default metric.
* \ie
*
* EXAMPLE
* .CS
* ifMetricSet ("mottsec0", metric);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifMetricGet()
*/
STATUS ifMetricSet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int metric /* Interface default metric */
)
{
return (ifIoctl (interfaceName, (int)SIOCSIFMETRIC, (_Vx_usr_arg_t)metric));
}
/*******************************************************************************
*
* ifMetricGet - get the metric for a network interface
*
* This routine retrieves the metric for a specified network interface.
* The metric is copied to the buffer <metric>.
*
*\is
* \i <interfaceName>
* The name for the interface.
* \i <metric>
* The location where the interface metric is copied.
* \ie
*
* EXAMPLE
* .CS
* int metric;
* ifMetricGet ("mottsec0", &metric);
* .CE
*
* RETURNS: OK or ERROR.
*
* SEE ALSO: ifMetricSet()
*/
STATUS ifMetricGet
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
int *metric /* buffer for interface default metric */
)
{
/* Warning for 64 bit! */
return ifIoctl(interfaceName, (int)SIOCGIFMETRIC, (_Vx_usr_arg_t)metric);
}
/****************************************************************************
*
* ifIndexToIfName - returns the interface name given the interface index
*
* This routine returns the interface name for the interface referenced
* by the <ifIndex> parameter.
*
* \is
* \i <ifIndex>
* The index for the interface.
* \i <ifname>
* The location where the interface name is copied
* \ie
*
* EXAMPLE
* .CS
* char *ifname;
* ifname = malloc(16);
* ifIndexToIfName (1, ifname);
* .CE
*
* RETURNS: OK on success, ERROR otherwise.
*/
extern STATUS ifIndexToIfName
(
unsigned short ifIndex, /* interface index */
char * ifname /* buffer for name of interface, i.e. ei0 */
)
{
if(ipcom_if_indextoname((Ip_u32)ifIndex,ifname)==IP_NULL)
return ERROR;
else
return OK;
}
/****************************************************************************
*
* ifNameToIfIndex - returns the interface index given the interface name
*
* This routine returns the interface index for the interface named by the
* <ifname> parameter, which provides a string describing the full interface
* name. For example, "fei0".
*
* \is
* \i <ifname>
* The name for the interface.
* \ie
*
* EXAMPLE
* .CS
* unsigned short ifindex;
* ifindex = ifNameToIfIndex ("mottsec0");
* .CE
*
* RETURNS: The interface index, if the interface could be located,
* 0 otherwise. 0 is not a valid value for interface index.
*/
extern unsigned short ifNameToIfIndex
(
char * ifname /* name of interface, i.e. ei0 */
)
{
return (unsigned short)ipcom_if_nametoindex(ifname);
}
/*******************************************************************************
* PRIVATE:*
*
* ipcom_proxy_sys_var : returns sysvar string for a given interface
* used for enabling or disabling proxy ARP on the interface
*
* retval : string represeting the sysvar
*
*/
LOCAL Ip_err ipcom_proxy_sys_var
(
char *interfaceName, /* name of interface to configure, i.e. ei0 */
char* enable
)
{
char *suffix=".inet.EnableNetworkProxyArp";
char *buffer=ipcom_malloc((ipcom_strlen(interfaceName)+ipcom_strlen(suffix)+1)*sizeof(char));
Ip_err status;
if(buffer)
{
ipcom_strncpy(buffer,interfaceName,ipcom_strlen(interfaceName)+1);
ipcom_strncat(buffer,suffix,ipcom_strlen(suffix));
}
else
{
return IPCOM_ERR_FAILED;
}
status=ipcom_sysvar_set(buffer,enable,IPCOM_SYSVAR_FLAG_OVERWRITE);
ipcom_free(buffer);
return status;
}
/*******************************************************************************
*
* ifProxyArpDisable - disables proxy Arp service on an interface
*
* This routine deactivates proxy services on the specified interface.
* It is an error to call this routine on an interface
* that does not support ARP (IFF_NOARP flag is set).
*
* \is
* \i <interfaceName>
* The name for the interface.
* \ie
*
* EXAMPLE
* .CS
* ifProxyArpDisable ("mottsec0");
* .CE
*
* RETURNS: OK, or ERROR if unsuccessful.
*
*/
extern STATUS ifProxyArpDisable
(
char *interfaceName /* name of interface to configure, i.e. ei0 */
)
{
int flags;
if(ifFlagGet(interfaceName,&flags)==ERROR || (flags & IFF_NOARP) ||(ipcom_proxy_sys_var(interfaceName,"0")!=IPCOM_SUCCESS))
return ERROR;
else
return OK;
}
/*******************************************************************************
*
* ifProxyArpEnable - enables proxy Arp service on an interface
*
* This routine activates proxy services on the specified interface. It is
* an error to call this routine on an interface
* that does not support ARP (IFF_NOARP flag is set).
*
* \is
* \i <interfaceName>
* The name for the interface.
* \ie
*
* EXAMPLE
* .CS
* ifProxyArpEnable ("mottsec0");
* .CE
*
* RETURNS: OK, or ERROR if unsuccessful.
*
*/
extern STATUS ifProxyArpEnable
(
char *interfaceName /* name of interface to configure, i.e. ei0 */
)
{
int flags;
if(ifFlagGet(interfaceName,&flags)==ERROR || (flags & IFF_NOARP) ||(ipcom_proxy_sys_var(interfaceName,"1")!=IPCOM_SUCCESS))
return ERROR;
else
return OK;
}
/*******************************************************************************
*
* ifRouteDelete - delete routes associated with a network interface
*
* This API is supported for backwards compatibility only.
*
* This routine deletes all routes that have been associated with the
* specified interface. For the purposes of this function, a route is
* associated with an interface if its destination equals to an assigned
* address or network number for the interface which has been added by the system.
*
* This routine does NOT remove routes to arbitrary destinations which
* pass through the given interface.
*
* NOTE
* This function only works for address family AF_INET.
*
* \is
* \i <ifName>
* The name for the interface.
* \i <unit>
* The unit for the interface.
* \ie
*
* EXAMPLE
* .CS
* ifRouteDelete ("mottsec", 0);
* .CE
*
* RETURNS:
* The number of routes deleted, or ERROR if an interface is not specified.
*/
int ifRouteDelete
(
char *ifName, /* name of the interface */
int unit /* unit number for this interface */
)
{
Ipcom_route *rtab;
Ipnet_netif *netif;
char fullIfName[IP_IFNAMSIZ];
ifLib_route_cb_data cb_data;
struct Ip_ifaddrs *ifaddr;
struct Ip_ifaddrs *ifaddrs;
struct Ip_sockaddr_in *s_in;
/* Create the full interface name to retrieve Ipnet_netif */
ipcom_sprintf(fullIfName, "%.*s%d", IP_IFNAMSIZ - 1, ifName,unit);
/* We've got to return the number of routes deleted, so initialize the count */
cb_data.count = 0;
/* Get pointer to network interface corresponding to input name */
netif = ipnet_if_nametonetif(ipnet_get_effective_vr(), fullIfName);
if (netif == IP_NULL)
{
logMsg("ifAllRoutesDelete: ERROR: Could not get netif from %s\n",
(_Vx_usr_arg_t)fullIfName,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0);
return ERROR;
}
cb_data.netif = netif;
/* Get interface addresses */
ipcom_getifaddrs(&ifaddrs);
for (ifaddr = ifaddrs; ifaddr != IP_NULL; ifaddr = ifaddr->ifa_next)
{
s_in = (struct Ip_sockaddr_in *) (ifaddr->ifa_addr);
cb_data.addr = s_in->sin_addr.s_addr;
if(ipnet_ip4_get_addr_type2(cb_data.addr, netif) == IPNET_ADDR_TYPE_UNICAST)
{
if (ipnet_route_get_rtab(IP_AF_INET, netif->vr_index,
IPCOM_ROUTE_TABLE_DEFAULT, &rtab) == 0)
{
ipcom_route_walk_tree(rtab,
(Ipcom_route_walk_cb) ifRouteDeleteCallback,&cb_data);
}
else
{
/* Free the interface addresses */
ipcom_freeifaddrs(ifaddrs);
logMsg("ifRouteDelete: ERROR: Could not walk route tree for %s\n",
(_Vx_usr_arg_t)fullIfName,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0);
return ERROR;
}
}
}
/* Free the interface addresses */
ipcom_freeifaddrs(ifaddrs);
return (int)(cb_data.count);
}
/******************************************************************************
*
* ifAllRoutesDelete - delete all routes associated with a network interface
*
* This routine deletes all routes that have been associated with the
* specified interface. The routes deleted are:
* \ml
* \m -
* the network route added when the interface address is initialized
* \m -
* the static routes added by the administrator
* \m -
* ARP routes passing through the interface
* \me
* Routes added by routing protocols are not deleted.
*
* INTERNAL
* This function only works for address family AF_INET.
*
* \is
* \i <ifName>
* The name for the interface.
* \i <unit>
* The unit for the interface.
* \ie
*
* EXAMPLE
* .CS
* ifAllRoutesDelete ("mottsec", 0);
* .CE
*
*
* RETURNS:
* The number of routes deleted, or ERROR if an interface is not specified.
*
* ERRNO: N/A
*/
int ifAllRoutesDelete
(
char * ifName, /* name of the interface */
int unit /* unit number for this interface */
)
{
Ipcom_route *rtab;
Ipnet_netif *netif;
char fullIfName[IP_IFNAMSIZ];
ifLib_route_cb_data cb_data;
struct Ip_ifaddrs *ifaddr;
struct Ip_ifaddrs *ifaddrs;
struct Ip_sockaddr_in *s_in;
ipcom_sprintf(fullIfName, "%.*s%d", IP_IFNAMSIZ - 1, ifName,unit);
/* Get pointer to network interface corresponding to input name */
netif = ipnet_if_nametonetif(ipnet_get_effective_vr(), fullIfName);
if (netif == IP_NULL)
{
logMsg("ifAllRoutesDelete: ERROR: Could not get netif from %s\n",
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0);
return ERROR;
}
cb_data.netif = netif;
cb_data.count = 0;
/* Get interface addresses */
ipcom_getifaddrs(&ifaddrs);
for (ifaddr = ifaddrs; ifaddr != IP_NULL; ifaddr = ifaddr->ifa_next)
{
s_in = (struct Ip_sockaddr_in *) (ifaddr->ifa_addr);
cb_data.addr = s_in->sin_addr.s_addr;
if(ipnet_ip4_get_addr_type2(cb_data.addr, netif) == IPNET_ADDR_TYPE_UNICAST)
{
if (ipnet_route_get_rtab(IP_AF_INET, netif->vr_index, IPCOM_ROUTE_TABLE_DEFAULT, &rtab) == 0)
{
ipcom_route_walk_tree(rtab,
(Ipcom_route_walk_cb) ifAllRoutesDeleteCallback,&cb_data);
}
else
{
/* Free the interface addresses */
ipcom_freeifaddrs(ifaddrs);
logMsg("ifAllRoutesDelete: ERROR: Could not walk route tree for %s\n",
(_Vx_usr_arg_t)fullIfName,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0,
(_Vx_usr_arg_t)0);
return ERROR;
}
ipnet_route_delete(AF_INET, ipnet_get_effective_vr(), &cb_data.addr);
}
}
/* Free the interface addresses */
ipcom_freeifaddrs(ifaddrs);
return (int)(cb_data.count);
}
/******************************************************************************
*
* ifRouteDeleteCallback - callback used by ifRouteDelete
*
* For each route in the table, this callback will delete routes to the
* specified interface address and network
* \m -
* Static routes and routes added by routing protocols are not deleted.
*
* INTERNAL
* This function only works for address family AF_INET.
*
* RETURNS:
* IP_TRUE if the route should be deleted, or IP_FALSE if the route should
* remain in the table.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
LOCAL Ip_bool ifRouteDeleteCallback (Ipnet_route_entry *rt, ifLib_route_cb_data *cb_data)
{
if (IP_BIT_ISTRUE(rt->hdr.flags, IPNET_RTF_STATIC | IPNET_RTF_DYNAMIC))
return IP_FALSE;
if (rt->netif && (rt->netif->ipcom.ifindex == cb_data->netif->ipcom.ifindex))
{
cb_data->count++;
return IP_TRUE;
}
return IP_FALSE;
}
/******************************************************************************
*
* ifAllRoutesDeleteCallback - callback used by ifAllRoutesDelete
*
* For each route in the table, this callback will delete static routes
* which use the interface as a gateway
* \m -
* Routes added by routing protocols are not deleted.
*
* INTERNAL
* This function only works for address family AF_INET.
*
* RETURNS:
* IP_TRUE if the route should be deleted, or IP_FALSE if the route should
* remain in the table.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
LOCAL Ip_bool ifAllRoutesDeleteCallback (Ipnet_route_entry *rt, ifLib_route_cb_data *cb_data)
{
struct Ip_sockaddr_in *rt_gwp = (struct Ip_sockaddr_in *)rt->gateway;
/* Delete routes which use the interface address as a gateway */
if (rt_gwp && rt_gwp->sin_family == IP_AF_INET
&& rt_gwp->sin_addr.s_addr == cb_data->addr)
{
cb_data->count++;
return TRUE;
}
/* Delete routes which use the local interface link as a gateway */
if (rt->netif && (rt->netif->ipcom.ifindex == cb_data->netif->ipcom.ifindex))
{
cb_data->count++;
return TRUE;
}
return IP_FALSE;
}