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
@@ -0,0 +1,508 @@
/* arpLib.c - Address Resolution Protocol (ARP) table manipulation library */
/*
* Copyright (c) 2006, 2008-2009, 2012-2014,2017 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.
*/
/*
modification history
--------------------
30nov17,rjq convert hostname to ip addr in arpDelete() (VXW6-86614)
26nov14,ljl Make arpFlush not to remove permanent ARP entry, VXW6-83339
20nov13,qsn Fix WIND00400655, make numTries work properly in arpResolve
01feb12,xhs Fix WIND00329362, arpResolve sends ARP Request for devices
already stored in ARP cache
25aug09,mry Fix WIND00175061 (arpResolve() api doesn't copy mac correctly)
16may08,kjn Add support for arpFlush and arpResolve
30aug06,tkf Writrten
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for arpXXX() APIS
available in the previous releases of the Wind River network stack.
The routines are now wrappers all implemented in terms of the preferred routine
ipnet_cmd_arp(), which is available in the IPNet stack.
The arpXXX() APIS provide direct access to the address translation table
maintained by the Address Resolution Protocol (ARP). Each entry in
the table maps an Internet Protocol (IP) address to a physical hardware
address. This library supports only those entries that translate between IP
and Ethernet addresses. It is linked into the VxWorks image if
INCLUDE_IPWRAP_ARP is defined at the time the image is built. The underlying
ARP protocol, which creates and maintains the table, is included automatically
as part of the IPNET2 component.
BEHAVIOURAL CHANGES
The utility arpShow() is automatically included if INCLUDE_IPWRAP_ARP is
included.
The wrappers for the APIs arpFlush() and arpResolve() have not been
implemented since ipnet_cmd_arp() does not have commands or options to support
those functions.
RELATED INTERFACES
A low level interface to the ARP table is available in IPNET2 with the
socket-specific IP_SIOCSARP, IP_SIOCDARP and IP_SIOCGARP ioctl functions.
INCLUDE FILES: arpLib.h
SEE ALSO: inetLib
*/
/* includes */
#include <arpa/inet.h>
#include <ipcom_err.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <drv/timer/timerDev.h> /* sysClkRateGet() */
#include <ipcom_sock2.h>
#include <ipcom_vxworks.h>
#include <ipnet.h>
#include <ipnet/ipioctl.h>
#include <arpLib.h>
#include <errnoLib.h>
#include <inetLib.h>
#include <sockLib.h>
/* defines */
#define ENET_SIZE 6 /* Ethernet address size */
#define IPWRAP_ARP_CMDNAME "arp"
#define IPWRAP_ARP_OPT_ADD "-s"
#define IPWRAP_ARP_OPT_DEL "-d"
#define IPWRAP_ARP_OPT_TMP "-t"
#define IPWRAP_ARP_OPT_PUB "-p"
#define IPWRAP_ARP_OPT_SHOW "-a"
#define IPWRAP_ARP_OPT_FLUSH "-F"
#define IPWRAP_ARP_OPT_RESOLVE "-r"
#define IPWRAP_ARPCMD_MAXARGS 16
/* forward static functions */
LOCAL STATUS etherAsciiToEnet (char * asciiAddr, u_char * retEnet);
IMPORT int hostGetByName (char *name);
IMPORT int ipnet_cmd_arp(int argc, char **argv);
STATUS arpShow(void);
void arpFlush (void);
STATUS arpResolve
(
char *targetAddr,
char *pHwAddr,
int numTries,
int numTicks
);
/*******************************************************************************
*
* arpHostToIpAddr - Converts a host name or address to a dotteted quad string.
*
* This routine converts a host name or address to a dotted quad string.
*
* RETURNS: Dotted quad string, or NULL if unsuccessful.
*
* ERRNO
* S_arpLib_INVALID_HOST
*/
LOCAL char * arpHostToIpAddr
(
char * pHost /* host name or IP address */
)
{
struct Ip_in_addr hostAddr;
char * pIpAddr;
/* See if the provided host name/address is valid */
if ((hostAddr.s_addr = (Ip_u32)ipcom_inet_addr (pHost)) != (Ip_u32)ERROR)
pIpAddr = pHost;
else if ((hostAddr.s_addr = (Ip_u32)hostGetByName (pHost)) != (Ip_u32)ERROR)
pIpAddr = ipcom_inet_ntoa (hostAddr);
else
{
errnoSet(S_arpLib_INVALID_HOST);
return NULL;
}
return pIpAddr;
}
/* globals */
/*******************************************************************************
*
* arpAdd - create or modify an ARP table entry
*
* This routine assigns an Ethernet address to an IP address in the ARP table.
* The <pHost> parameter specifies the host by name or by Internet address
* using standard dotted decimal notation. The <pEther> parameter provides the
* Ethernet address as six hexadecimal bytes (between 0 and ff) separated by
* colons. A new entry is created for the specified host if necessary.
* Otherwise, the existing entry is changed to use the given Ethernet address.
*
* The <flags> parameter combines any of the following options:
* \is
* \i 'IP_ATF_PERM (0x04)'
* Create a permanent ARP entry which will not time out. It is defined in ipcom_sock.h
* \i 'IP_ATF_PUBL (0x08)'
* Publish this entry. The host will respond to ARP requests even if the
* <pHost> parameter does not match a local IP address. This setting provides
* a limited form of proxy ARP. It is defined in ipcom_sock.h
* \ie
*
* FUNCTIONAL CHANGES
* \is
* \i The flag 'IP_ATF_PROXY (0x10)' is not supported in this implementation.
* \ie
*
* EXAMPLE
* Create a permanent ARP table entry for the host named "myHost" with
* Ethernet address 0:80:f9:1:2:3:
* \CS
* arpAdd ("myHost", "0:80:f9:1:2:3", 0x4);
* \CE
*
* Assuming "myHost" has the Internet address "90.0.0.3", the following call
* changes the Ethernet address to 0:80:f9:1:2:4. No additional flags are set
* for that entry.
* \CS
* arpAdd ("90.0.0.3", "0:80:f9:1:2:4", 0);
* \CE
*
* RETURNS: OK, or ERROR if unsuccessful.
*
* ERRNO:
* S_arpLib_INVALID_ARGUMENT
* S_arpLib_INVALID_HOST
* S_arpLib_INVALID_ENET_ADDRESS
* S_arpLib_INVALID_FLAG
* or results of low-level ioctl call.
*/
STATUS arpAdd
(
char * pHost, /* host name or IP address */
char * pEther, /* Ethernet address */
int flags /* ARP flags */
)
{
u_char ea [ENET_SIZE]; /* Ethernet address */
int argc;
char * argv [IPWRAP_ARPCMD_MAXARGS];
char * pIpAddr;
if ((pHost == NULL) || (pEther == NULL)) /* validate parameters */
{
errnoSet(S_arpLib_INVALID_ARGUMENT);
return (ERROR);
}
pIpAddr = arpHostToIpAddr(pHost);
if (pIpAddr == NULL)
return (ERROR);
/* See if the provided ethernet address is valid */
if (etherAsciiToEnet (pEther, ea) != OK)
{
errnoSet(S_arpLib_INVALID_ENET_ADDRESS);
return (ERROR);
}
/* validate flags */
if (flags & ~(IP_ATF_PERM | IP_ATF_PUBL))
{
errnoSet(S_arpLib_INVALID_FLAG);
return (ERROR);
}
argc = 0;
argv [argc++] = IPWRAP_ARP_CMDNAME;
if (flags & IP_ATF_PUBL)
argv [argc++] = IPWRAP_ARP_OPT_PUB;
/* For ipnet_arp_cmd(), the default is permanent */
if ((flags & IP_ATF_PERM) == 0)
argv [argc++] = IPWRAP_ARP_OPT_TMP;
argv [argc++] = IPWRAP_ARP_OPT_ADD;
argv [argc++] = pIpAddr;
argv [argc++] = pEther;
argv [argc] = NULL;
if (ipnet_cmd_arp (argc, argv) < 0)
return (ERROR);
return (OK);
}
/*******************************************************************************
*
* arpDelete - remove an ARP table entry
*
* This routine deletes an ARP table entry. The <pHost> parameter indicates
* the target entry using the host name or Internet address.
*
* EXAMPLE
* Tp delete an arp entry corresponding to host named "myHost" with IP
* address of "91.0.0.3", use either of the commands below:
* \CS
* arpDelete ("91.0.0.3")
* arpDelete ("myHost")
* \CE
*
* RETURNS: OK, or ERROR if unsuccessful.
*
* ERRNO
* S_arpLib_INVALID_ARGUMENT
* S_arpLib_INVALID_HOST
*/
STATUS arpDelete
(
char * pHost /* host name or IP address */
)
{
struct arpreq req;
struct sockaddr_in *sin = (struct sockaddr_in *)&req.arp_pa;
int fd;
int ret;
char *pIpAddr;
pIpAddr = arpHostToIpAddr(pHost);
if (pIpAddr == NULL)
return (ERROR);
memset(&req, 0, sizeof(req));
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
if (inet_pton(AF_INET, pIpAddr, &sin->sin_addr) != 1)
{
errnoSet(S_arpLib_INVALID_HOST);
return ERROR;
}
ret = fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd >= 0)
{
ret = ioctl(fd, SIOCDARP, &req);
close(fd);
}
if (ret < 0)
{
if (ipcom_errno == IP_ERRNO_ENXIO
|| ipcom_errno == IP_ERRNO_EPROTONOSUPPORT
|| ipcom_errno == IP_ERRNO_ESRCH)
errnoSet(S_arpLib_INVALID_HOST);
else
errnoSet(S_arpLib_INVALID_ARGUMENT);
return ERROR;
}
return OK;
}
/*******************************************************************************
*
* etherAsciiToEnet - convert Ethernet address
*
* This routine converts an Ethernet address in ascii format to its normal
* 48 bit format. <asciiAddr> is the string Ethernet address which has the
* form "x:x:x:x:x:x" where x is a hexadecimal number between 0 and ff.
* <retEnet> is where the Ethernet address gets returned. This routine is
* similar to the UNIX call ether_aton.
*
* RETURNS: OK, or ERROR if unsuccessful.
*
* ERRNO: S_arpLib_INVALID_ENET_ADDRESS
*
* NOMANUAL
*/
LOCAL STATUS etherAsciiToEnet
(
char * asciiAddr, /* enet addr in ascii */
u_char * retEnet /* return enet addr */
)
{
int enet [ENET_SIZE]; /* Ethernet address */
int ix; /* index variable */
if (sscanf (asciiAddr, "%x:%x:%x:%x:%x:%x", &enet [0],
&enet [1], &enet [2], &enet [3], &enet [4],
&enet [5]) != ENET_SIZE)
{
printf ("arp: invalid Ethernet address %s\n", asciiAddr);
errnoSet(S_arpLib_INVALID_ENET_ADDRESS);
return (ERROR);
}
for (ix = 0; ix < ENET_SIZE; ix++)
retEnet [ix] = (u_char) enet [ix];
return (OK);
}
/*******************************************************************************
*
* arpShow - Display the currently existing ARP entries.
*
* This routine displays the currently existing ARP entries.
*
* RETURNS: OK, or ERROR if unsuccessful.
*
* ERRNO
* N/A
*/
STATUS arpShow
(
void
)
{
int argc = 2;
char * argv [] = {
IPWRAP_ARP_CMDNAME,
IPWRAP_ARP_OPT_SHOW,
NULL
};
if (ipnet_cmd_arp (argc, argv) < 0)
return (ERROR);
return OK;
}
/*******************************************************************************
*
* arpFlush - flush all non-permanent entries in the system ARP table
*
* This routine flushes all non-permanent entries in the ARP cache.
*
* RETURNS: N/A
*
* NOMANUAL
*/
void arpFlush (void)
{
int argc = 2;
char * argv [] = {
IPWRAP_ARP_CMDNAME,
IPWRAP_ARP_OPT_FLUSH,
NULL
};
(void)ipnet_cmd_arp (argc, argv);
}
/*******************************************************************************
*
* arpResolve - resolve a hardware address for a specified Internet address
*
* This routine uses the Address Resolution Protocol (ARP) and internal ARP
* cache to resolve the hardware address of a machine that owns the Internet
* address given in <targetAddr>.
*
* The hardware address is copied to <pHwAddr> as network byte order, if the
* resolution of <targetAddr> is successful. <pHwAddr> must point to a buffer
* which is large enough to receive the address.
*
* NOTE: RFC 1122 prohibits sending more than one arp request per second. Any
* numTicks value that would result in a shorter time than this is adjusted to
* a value corresponding to one second.
*
* RETURNS:
* OK if the address is resolved successfully, or ERROR if <pHwAddr> is NULL,
* <targetAddr> is invalid, or address resolution is unsuccessful.
*
* ERRNO:
* S_arpLib_INVALID_ARGUMENT
* S_arpLib_INVALID_HOST
*
*/
STATUS arpResolve
(
char *targetAddr, /* name or Internet address of target */
char *pHwAddr, /* where to return the H/W address */
int numTries, /* number of times to try ARPing */
/* (-1 means try forever) */
int numTicks /* number of ticks between ARPs */
)
{
char * pIpAddr;
int sock;
STATUS status = ERROR;
int argc = 2;
char * argv [] = {
IPWRAP_ARP_CMDNAME,
IPWRAP_ARP_OPT_RESOLVE,
NULL,
NULL
};
int num = 0;
int hz = sysClkRateGet();
int waitNumTicks = numTicks < hz ? hz : numTicks;
pIpAddr = arpHostToIpAddr(targetAddr);
if (pIpAddr == NULL)
return status;
argv[argc++] = pIpAddr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
return status;
/* numTries == -1 means "probe forever" */
while (numTries == -1 || num++ <= numTries)
{
char arpreq_buf[sizeof(struct arpreq) + sizeof(struct sockaddr_storage)];
struct arpreq *req;
struct sockaddr_in *pa;
req = (void*) arpreq_buf;
pa = (void *) &req->arp_pa;
/* Get the MAC address */
bzero((caddr_t) req, sizeof(*req));
pa->sin_family = AF_INET;
pa->sin_len = sizeof(*pa);
(void)inet_pton(AF_INET, pIpAddr, &pa->sin_addr);
if (ioctl(sock, (int)SIOCGARP, req) == 0)
{
status = OK;
if (pHwAddr != NULL)
bcopy ((caddr_t) LLADDR(&req->arp_ha),
(caddr_t) pHwAddr,
ENET_SIZE);
break;
}
if (numTries != -1 && (num <= 0 || num > numTries))
break;
/* Send probe */
if (ipnet_cmd_arp (argc, argv) < 0)
break;
/* Wait for ARP to finish */
taskDelay(waitNumTicks);
}
close(sock);
return status;
}
@@ -0,0 +1,412 @@
/* getaddrinfo.c - Hostname-Internet address-Translation library */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01f,27mar07,dlk Fix RTP use with NULL pHostname or pServname (WIND00091726).
01e,19feb07,dlk Address WIND00088385.
01d,21nov06,tlu Change the return code of getaddrinfo () to EAI_MEMORY when
malloc fails and modify the error return handling from kernel
to RTP
01c,28sep06,tlu Port getaddrinfo() to RTP and fix the return code
to EAI_XXX for apigen to conform with standard
01b,31jul06,tkf Correct function description for apigen. Added freeaddrinfo()
wrapper.
01a,26jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine getaddrinfo(), a function
that provides for IP node name-address-translation.
INCLUDE FILES: wrapper/wrapperHostLib.h
*/
/* includes */
#include <sys/socket.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
#include <wrapper/wrapperHostLib.h>
#ifndef _WRS_KERNEL
#include <stdio.h>
#include <stdlib.h>
#include <hostLib.h>
#include <sys/sysctl.h>
#include <string.h>
static struct addrinfo * copy_ai(const struct addrinfo *pai);
/* The max buffer size to store addrinfo structures for sysctl */
#define MAX_ADDRINFO_BLOCK 64*1024
#endif
/* defines */
/* enums */
/* typedefs */
struct addrinfo;
/* locals */
/* This struct is used by gai_strerror. */
static struct ai_errlist {
const char *str;
int code;
} ai_errlist[] = {
{ "Success", 0 },
{ "Invalid value for ai_flags", IP_EAI_BADFLAGS },
{ "Non-recoverable failure in name resolution", IP_EAI_FAIL },
{ "ai_family not supported", IP_EAI_FAMILY },
{ "Memory allocation failure", IP_EAI_MEMORY },
{ "hostname nor servname provided, or not known", IP_EAI_NONAME },
{ "servname not supported for ai_socktype", IP_EAI_SERVICE },
{ "ai_socktype not supported", IP_EAI_SOCKTYPE },
{ "System error returned in errno", IP_EAI_SYSTEM },
/* backward compatibility with userland code prior to 2553bis-02 */
{ "Address family for hostname not supported", 1 },
{ "No address associated with hostname", 7 },
{ NULL, -1 },
};
/*******************************************************************************
*
* getaddrinfo - node name-to-address translation
*
* This routine needs an IP node name (for example, the host or router node),
* an IP address in <hostname>, and/or a service name (such as "ftp") in
* <servname>. The routine provides a linked list of 'addrinfo' structures
* in <res>. <res> must be freed with 'freeaddrinfo' after use to avoid
* memory leaks. The address information is returned in network byte order.
*
* The search can be narrowed by specifying different flags for <hints> or can
* be NULL. (See below). The search starts in the host table; if the search
* cannot be satisfied there, a DNS request is carried out (if a DNS server
* has been initialized).
*
* The 'addrinfo' structure is as follows:
* \cs
* struct addrinfo
* {
* int ai_flags; -> AI_PASSIVE, ...
* int ai_family; -> AF_INET, AF_INET6, AF_UNSPEC
* int ai_socktype; -> SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ANY
* int ai_protocol; -> IPPROTO_TCP, IPPROTO_ICMP, ...
* size_t ai_addrlen; -> length of ai_addr
* Don't use for hints!
* char *ai_canonname; -> ptr to canonical name of host
* Don't use for hints!
* struct sockaddr *ai_addr; -> ptr to socket address structure
* Don't use for hints!
* struct addrinfo *ai_next; -> ptr to next structure in linked list
* Don't use for hints!
* };
* \ce
* The following flags are defined:
* \is
* \i AI_PASSIVE
* Specifies the returned address when the <hostname> is null. If this
* flag is specified the returned address must be suitable for use in
* a call to bind() by a server accepting incoming connections; the
* address will be INADDR_ANY or IN6ADDR_ANY_INIT in this case. Otherwise,
* the returned address must be suitable for a call to connect() (or
* sendto() or sendmsg() for a connectionless protocol), and the address
* in this case will be the loopback address. This flag is ignored
* if the <hostname> is not null.
* \i AI_CANONNAME
* If this flag is set and <hostname> is not NULL, then
* the <ai_canonname> member of the first addrinfo returned will
* point to a string containing the canonical name corresponding to
* <hostname>. However, if the canonical name cannot be located or
* <hostname> is a numeric host string, then <ai_canonname> will be
* <hostname> or a string with the same contents.
* \i AI_NUMERICHOST
* When this flag is set and a non-NULL <hostname> is provided, the
* <hostname> must be a numeric host address string, or EAI_NONAME
* will be returned. This flag prevents using any type of name resolution
* service (for example, DNS).
* \i AI_V4MAPPED
* If no IPv6 record is found in either the host table or DNS,
* a request for IPv4 records is sent and the found IPv4 address
* is returned as IPv4-mapped IPv6 address.
* Used for IPv6 (AF_INET6) only.
* \i AI_ADDRCONFIG
* If this flag is specified, an IPv4 address is returned only if
* an IPv4 address is configured for the local system, while an
* IPv6 address is returned only if at least one non-loopback IPv6
* address is locally configured.
* \ie
* EXAMPLE
* \cs
* struct addrinfo hints, *res;
*
* bzero ((char *) &hints, sizeof (hints));
* hints.ai_flags = AI_V4MAPPED;
* hints.ai_family = AF_INET6;
*
* getaddrinfo ("alpha","ftp",&hints,&res);
* \...
* freeaddrinfo (res);
* \ce
*
* RETURNS
* The return value is zero if the call is successful. Otherwise,
* a numeric error code is returned that can be converted into a string with
* gai_strerror() (see netdb.h).
* \is
* \i EAI_BADFLAGS
* This error code is currently not returned.
* \i EAI_FAIL
* A non-recoverable failure in name resolution occurred.
* \i EAI_FAMILY
* The specified 'ai_family' is not supported.
* \i EAI_MEMORY
* A memory allocation failure occurred.
* \i EAI_NONAME
* No <hostname> or <servname> is provided, or the provided one is not known.
* \i EAI_SERVICE
* The provided <servname> is not supported for 'ai_socktype'.
* \i EAI_SOCKTYPE
* The value of 'ai_socktype' is not supported.
* \i EAI_SYSTEM
* A system error was returned in 'errno'.
* \i 0
* Returns zero if OK.
* \ie
* ERRNO
* N/A
* BEHAVIOUR CHANGES
*
* The following flags are not supported:
* \is
* \i AI_NUMERICSERV
* \ie
* The following error codes are not currently returned.
* \is
* \i EAI_BADHINTS
* \i EAI_BADFLAGS
* \ie
*
*/
int getaddrinfo
(
const char * pHostname,
const char * pServname,
const struct addrinfo * pHints,
struct addrinfo ** ppRes
)
{
#ifdef _WRS_KERNEL
int errCode;
/*
* TODO (TKF):
*
* Need to add support for the AI_NUMERICSERV flag as described below:
*
* When this flag is set and a non-NULL <servname> is provided,
* <servname> must be a numeric port number string, or else EAI_NONAME
* will be returned. This flag prevents any service name resolution
* from being attempted.
*/
/*
* TODO (TKF):
*
* Need to return IP_EAI_BADHINTS for cases described below:
*
* The value for <hints> is invalid.
*/
/*
* TODO (TKF):
*
* Need to return IP_EAI_BADFLAGS for cases described below:
*
* The value for 'ai_flags' is invalid.
*/
errCode = ipcom_getaddrinfo(pHostname, pServname,
(IP_CONST struct Ip_addrinfo *)pHints,
(struct Ip_addrinfo **)ppRes);
return errCode;
#else /* RTP */
int mib [2];
struct addrinfoArgs addrinfoParams;
struct addrinfo * src;
struct addrinfo ** ppAi = ppRes;
struct addrinfo * ai;
void * buf;
char * end;
size_t len;
int error;
*ppAi = NULL; /* just in case the caller tries freeaddrinfo() on an error */
if ((pHostname == NULL) && (pServname == NULL))
{
return (EAI_NONAME);
}
mib[0] = CTL_NET;
mib[1] = ADDRINFO;
addrinfoParams.hostname = pHostname;
addrinfoParams.hostnamelen = pHostname ? strlen (pHostname) : 0;
addrinfoParams.servname = pServname;
addrinfoParams.servnamelen = pServname ? strlen (pServname) : 0;
addrinfoParams.hints = pHints;
/* Allocate the maximum buffer size 64K to hold addrinfo structures */
len = MAX_ADDRINFO_BLOCK;
buf = malloc (len);
if (buf == NULL)
{
printf("ERR: getaddrinfo failed in allocating memory for sysctl\n");
return (EAI_MEMORY);
}
if (sysctl (mib, 2, buf, &len, &addrinfoParams,
sizeof (addrinfoParams)) < 0)
{
printf ("sysctl() returned ERROR, errno=0x%x\n", errno);
free (buf);
return (EAI_SYSTEM); /* errno holds more descriptive error */
}
/*
* Walk through the addrinfo structures stored in buf to unpack them
* into a list. Note, the pointers in the addrinfo structures are
* incorrect (unless NULL). Since sysctl() did not fail, we know
* we have the whole packed list in buf.
*/
error = *((int *)buf); /* return value from kernel getaddrinfo() */
if (error == 0)
{
/* getaddrinfo() guarantees at least one addrinfo structure
on success */
end = (char *)buf + sizeof (int);
do
{
src = (struct addrinfo *) end;
ai = malloc (sizeof (struct addrinfo));
if (ai == NULL)
goto fail;
*ai = *src; /* copy most fields */
*ppAi = ai;
ppAi = &ai->ai_next;
ai->ai_next = NULL;
ai->ai_canonname = NULL;
ai->ai_addr = malloc (ai->ai_addrlen);
if (ai->ai_addr == NULL)
goto fail;
memcpy (ai->ai_addr, src + 1, ai->ai_addrlen);
end = (char *)(src + 1) + ai->ai_addrlen;
if (src->ai_canonname != NULL)
{
len = strlen (end) + 1;
ai->ai_canonname = malloc (len);
if (ai->ai_canonname == NULL)
goto fail;
memcpy (ai->ai_canonname, end, len);
/* round up to sizeof(int) boundary */
len = (len + sizeof(int) - 1) & ~(sizeof(int) - 1);
end += len;
}
} while (src->ai_next != NULL);
}
free(buf);
return error;
fail:
freeaddrinfo(*ppRes); /* OK if NULL */
free(buf);
return EAI_MEMORY;
#endif /* _WRS_KERNEL */
}
/*******************************************************************************
*
* gai_strerror - convert a numeric error code into a string
*
* DESCRIPTION
* This routine uses 'ai_errlist' to convert an error code returned by
* getaddrinfo() into a string.
*
* RETURNS: The error string.
*
* ERRNO: N/A
*
* SEE ALSO: netdb.h
*/
char * gai_strerror
(
int ecode
)
{
struct ai_errlist *p;
for (p = ai_errlist; p->str; p++) {
if (p->code == ecode)
return (char *)p->str;
}
return "Unknown error";
}
/*******************************************************************************
*
* freeaddrinfo - free allocated memory for structure addrinfo
*
* This routine frees the allocated memory for the linked list of addrinfo
* structures and for the canonical name string. ai should point to the first
* element of a list of addrinfo structures returned by getaddrinfo().
*
* RETURNS: N/A
*/
void freeaddrinfo
(
struct addrinfo * pAi
)
{
ipcom_freeaddrinfo ((struct Ip_addrinfo *)pAi);
}
@@ -0,0 +1,131 @@
/* gethostbyaddr.c - Hostname-Internet address-Translation library */
/*
* Copyright (c) 2006-2007 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.
*/
/*
modification history
--------------------
01c,27feb07,dlk Make the wrapper reentrant.
01b,23aug06,??? Add aroutine to init gethostbyaddr.c.
01a,27jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine gethostbyaddr(),
a function that provides for IP node name-address-translation.
INCLUDE FILES: net/utils/gethostbyaddr.h
*/
/* includes */
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <vxWorks.h>
#include <sys/socket.h>
#include <string.h>
#include <hostLib.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
/* defines */
#define HOSTENT_BUF_SIZE 512
/* enums */
/* typedefs */
typedef union _HOSTENT_BUF_U
{
void * p; /* for alignment */
double d; /* for alignment */
char b [HOSTENT_BUF_SIZE];
} HOSTENT_BUF_U;
struct hostent;
/* locals */
/* externs */
IMPORT FUNCPTR _gethostbyaddr;
/*******************************************************************************
*
* gethostbyaddr - get the name of a host, given the host address
*
* This routine performs a host table lookup and possibly a DNS search to query
* the given host address pointed to by <pAddr>. It returns the host name.
* <pAddr> points to an object of type 'struct in_addr' or 'struct in6_addr'
* depending on the address family, <type>.
* The address at <pAddr> is specified in network byte order.
*
* BEHAVIOUR CHANGE
* By default, the hostLib.h header file defines the macro
* GETHOSTBYADDR_REENTRANT; this provides backwards compatibility with
* previous versions of the Wind River network stack, and requires that the
* returned 'hostent' structure be freed using the hostentFree() function, when
* the application is done with it. If this module is recompiled with
* GETHOSTBYADDR_REENTRANT undefined, gethostbyaddr() returns a statically
* alocated memory area for the 'hostent' structure, and it is not necessary
* to call hostentFree() to free the returned 'hostent'; it is in fact wrong
* to do so.
*
* RETURNS
* A pointer to a 'struct hostent', upon success; or NULL, if an error occurred.
*
* ERRNO
* N/A
*/
struct hostent * gethostbyaddr
(
const char * pAddr,
int len,
int type
)
{
#ifdef GETHOSTBYADDR_REENTRANT
struct Ip_hostent he;
struct Ip_hostent * hp;
struct hostent * hp2;
HOSTENT_BUF_U hb;
int err = errno;
hp = ipcom_gethostbyaddr_r (pAddr, len, type,
&he, hb.b, sizeof (hb), &err);
if (hp == NULL)
{
errnoSet (err);
return NULL;
}
/* Make a copy of the hostent which may be freed with hostentFree() */
hp2 = hostentAlloc();
if (hp2 == NULL)
return NULL;
/* Note, HOSTENT_ALLOC_MAXNAME is bigger than HOSTENT_BUF_SIZE */
strlcpy (hp2->h_name, hp->h_name, HOSTENT_ALLOC_MAXNAME);
/* We only copy one IPv4 address and no alias; at present, that's all
* ipcom_gethostbyaddr_r() will ever give us.
*/
hp2->h_addrtype = hp->h_addrtype;
hp2->h_length = hp->h_length;
bcopy (hp->h_addr_list[0], hp2->h_addr_list[0], (size_t)(hp2->h_length));
return hp2;
#else /* !defined GETHOSTBYADDR_REENTRANT */
return (struct hostent *)ipcom_gethostbyaddr (pAddr, len, type);
#endif /* !defined GETHOSTBYADDR_REENTRANT */
}
@@ -0,0 +1,127 @@
/* gethostbyname.c - Hostname-Internet address-Translation library */
/*
* Copyright (c) 2006, 2007 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.
*/
/*
modification history
--------------------
01c,07mar07,dlk Restore reentrancy of gethostbyname().
01b,23aug06,tkf Add a routine to init gethostbyname.
01a,27jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine gethostbyname(),
a function that provides for IP node name-address-translation.
INCLUDE FILES: net/utils/gethostbyname.h
*/
/* includes */
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <vxWorks.h>
#include <sys/socket.h>
#include <string.h>
#include <hostLib.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
/* defines */
#define HOSTENT_BUF_SIZE 512
/* enums */
/* typedefs */
typedef union _HOSTENT_BUF_U
{
void * p; /* for alignment */
double d; /* for alignment */
char b [HOSTENT_BUF_SIZE];
} HOSTENT_BUF_U;
/* locals */
/* externs */
IMPORT FUNCPTR _gethostbyname;
/*******************************************************************************
*
* gethostbyname - get the address of a host, given the host name
*
* This routine performs a host table lookup and possibly a DNS search to query
* the given host name. It returns the internet address (in network byte order)
* and the alias (if any) for this host name.
*
* BEHAVIOUR CHANGE
* By default, the hostLib.h header file defines the macro
* GETHOSTBYNAME_REENTRANT; this provides backwards compatibility with
* previous versions of the Wind River network stack, and requires that the
* returned 'hostent' structure be freed using the hostentFree() function, when
* the application is done with it. If this module is recompiled with
* GETHOSTBYNAME_REENTRANT undefined, gethostbyname() returns a statically
* alocated memory area for the 'hostent' structure, and it is not necessary
* to call hostentFree() to free the returned 'hostent'; it is in fact wrong
* to do so.
*
* RETURNS
* A pointer to a 'struct hostent' upon success; or NULL, if an error occurred.
*
* ERRNO
* N/A
*/
struct hostent * gethostbyname
(
const char * pName /* node name or address string */
)
{
#ifdef GETHOSTBYNAME_REENTRANT
struct Ip_hostent he;
struct Ip_hostent * hp;
struct hostent * hp2;
HOSTENT_BUF_U hb;
int err = errno;
hp = ipcom_gethostbyname_r (pName, &he, hb.b, sizeof (hb), &err);
if (hp == NULL)
{
errnoSet (err);
return NULL;
}
/* Ugh, make a copy of the hostent which may be freed with hostentFree() */
hp2 = hostentAlloc();
if (hp2 == NULL)
return NULL;
/* Note, HOSTENT_ALLOC_MAXNAME is bigger than HOSTENT_BUF_SIZE */
strlcpy (hp2->h_name, hp->h_name, HOSTENT_ALLOC_MAXNAME);
/* We only copy one IPv4 address and no alias; at present, that's all
* ipcom_gethostbyname_r() will ever give us.
*/
hp2->h_addrtype = hp->h_addrtype;
hp2->h_length = hp->h_length;
bcopy (hp->h_addr_list[0], hp2->h_addr_list[0], (size_t)(hp2->h_length));
return hp2;
#else /* !defined GETHOSTBYNAME_REENTRANT */
return (struct hostent *)ipcom_gethostbyname (pName);
#endif /* !defined GETHOSTBYNAME_REENTRANT */
}
@@ -0,0 +1,99 @@
/* getifaddrs.c - get interface addresses */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01a,20nov06,kch Written.
*/
/*
DESCRIPTION
This library provides backward-compatible interface addresses routines for
getifaddrs() and freeifaddrs(). The routines are now a wrapper implemented in
terms of the preferred ipcom_getifaddrs() and ipcom_freeifaddrs().
*/
#include <vxWorks.h>
#include <net/ifaddrs.h>
#include <ipcom_vxworks.h>
#include <ipcom_sock2.h>
#include <ipcom_err.h>
/*****************************************************************************
*
* getifaddrs - get interface addresses
*
* This routine stores a reference to a linked list of the network interfaces
* in the memory referenced by ifap. The list consists of ifaddrs structures,
* as defined in the include file <ifaddrs.h>. The ifaddrs structure contains
* at least the following entries:
*
* struct ifaddrs *ifa_next;
* char *ifa_name;
* u_int ifa_flags;
* struct sockaddr *ifa_addr;
* struct sockaddr *ifa_netmask;
* struct sockaddr *ifa_dstaddr;
* void *ifa_data;
*
* The ifa_next field contains a pointer to the next structure on the list.
* This field is NULL in last structure on the list.
*
* The ifa_name field contains the interface name.
*
* The ifa_flags field contains the interface flags.
*
* The ifa_addr field references either the address of the interface or the
* link level address of the interface, if one exists, otherwise it is NULL.
* (The sa_family field of the ifa_addr field should be consulted to determine
* the format of the ifa_addr address.)
*
* The ifa_netmask field references the netmask associated with ifa_addr, if
* one is set, otherwise it is NULL.
*
* The ifa_dstaddr field references the destination address on a P2P interface,
* if one exists, otherwise it contains the broadcast address.
*
* Note that as a convenience, ifa_broadaddr is defined by a compiler #define
* directive to be the same as ifa_dstaddr.
*
* The ifa_data field references address family specific data. This field is
* currently not supported.
*
* RETURNS: 0 if sucessful; otherwise, the value -1 is returned.
*
* NOMANUAL
*/
int getifaddrs (struct ifaddrs **ifa)
{
return ipcom_getifaddrs ((struct Ip_ifaddrs **)ifa);
}
/******************************************************************************
*
* freeifaddrs - free returned getifaddrs data structures
*
* This routine free the dynamically allocated interface addresses array
* returned by getifaddrs().
*
* ERRNO: N/A
*
* NOMANUAL
*/
void freeifaddrs (struct ifaddrs *ifa)
{
ipcom_freeifaddrs ((struct Ip_ifaddrs *)ifa);
}
@@ -0,0 +1,188 @@
/* getnameinfo.c - Hostname-Internet address-Translation library */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01c,16sep06,tlu Ported the function getnameinfo() to RTP
01b,31jul06,tkf Correct function description for apigen.
01a,27jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine getnameinfo(), a function
that provides for IP node name-address-translation.
INCLUDE FILES: wrapper/wrapperHostLib.h
*/
/* includes */
#include <sys/socket.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
#ifndef _WRS_KERNEL
#include <sys/sysctl.h>
#include <hostLib.h>
#endif
#include <wrapper/wrapperHostLib.h>
/* defines */
/* enums */
/* typedefs */
struct sockaddr;
/* locals */
/*******************************************************************************
*
* getnameinfo - translates a socket address to a node name and service name
*
* *
* This function needs a socket address and provides an IP node name and/or
* service name. The caller allocates space for host with hostlen (e.g.
* NI_MAXHOST + 1) and serv with servlen (e.g. NI_MAXSERV + 1). If the caller
* doesn't want the host name or service name he must specify a hostlen or
* servlen of 0. The routine accesses the host table and/or DNS.
*
* The following flags are defined:
* \is
* \i NI_NUMERICHOST
* The numeric form of the host's address is returned instead
* of its name, under all circumstances.
* \i NI_NAMEREQ
* An error is returned if the host's name can't be located.
* \i NI_NUMERICSERV
* The numeric form of the service address is returned instead
* of its name, under all circumstances.
* \i NI_DGRAM
* Indicates that the service is a datagram service (SOCK_DGRAM).
* Default behavior is to assume the service is a stream
* service (SOCK_STREAM).
* \ie
* EXAMPLE
* \cs
* char hostName[NI_MAXHOST + 1];
* char servName[NI_MAXSERV + 1];
* int flags;
* struct sockaddr_in sockaddr4;
*
* bzero((char *) &sockaddr4, sizeof(sockaddr4));
* sockaddr4.sin_len = 16;
* sockaddr4.sin_family = AF_INET;
* sockaddr4.sin_port = htons(69); -> TFTP
* sockaddr4.sin_addr.s_addr = inet_addr("192.168.0.1");
* flags = NI_DGRAM;
*
* getnameinfo((sockaddr *) &sockaddr4, sockaddr4.sin_len,
* hostName, NI_MAXHOST, servName, NI_MAXSERV, flags);
* \ce
*
* RETURNS
* \is
* \i 0
* Returns zero, if OK.
* \i EAI_AGAIN
* The name could not be resolved at this time.
* Future attemts may succeed.
* \i EAI_FAIL
* A non-recoverable error occured
* \i EAI_MEMORY
* There was a memory allocation error
* \i EAI_NONAME
* The name does not resolve for the supplied parameters.
* NI_NAMEREQD is set and the host name cannot be located,
* or both nodename and servname were null.
* \i EAI_SYSTEM
* A system error occured. The error code can be found in
* errno.
* \ie
* ERRNO
* N/A
* BEHAVIUOR CHANGES
* The followinf flags are not currently supported.
* \is
* \i NI_NUMERICSCOPE
* \ie
*
*/
int getnameinfo
(
const struct sockaddr * pSa, /* socket address to be translated */
socklen_t salen, /* depends on AF_INET(6) */
char * pHost, /* node name or address string */
size_t hostlen, /* length of node name buffer */
char * pServ, /* service name or port number string */
size_t servlen, /* length of service name buffer */
int flags
)
{
#ifdef _WRS_KERNEL
int errCode = 0;
/*
* TODO (TKF):
*
* NI_NUMERICSCOPE needs to be supported with the following description:
*
* The numeric form of the scope identifier is returned instead
* of its name. IPv6 only, ignored otherwise.
*/
if ((errCode = ipcom_getnameinfo ((IP_CONST struct Ip_sockaddr *)pSa,
(Ip_socklen_t)salen, pHost,
(Ip_size_t)hostlen, pServ,
(Ip_size_t)servlen, flags))
== IPCOM_SUCCESS)
{
return 0;
}
errnoSet (IPCOM_ERRNO(errCode));
return errCode;
#else
struct nameinfoArgs hostParams;
int mib [2];
size_t size = sizeof (struct nameinfoArgs);
hostParams.sa = pSa;
hostParams.salen = salen;
hostParams.host = pHost;
hostParams.hostlen = hostlen;
hostParams.serv = pServ;
hostParams.servlen = servlen;
hostParams.flags = flags;
mib [0] = CTL_NET;
mib [1] = NAMEINFO;
/* Initialize errno to ensure we return the correct status. */
errno = 0;
(void) sysctl (mib, 2, &hostParams, &size, NULL, 0);
return (errno);
#endif
}
@@ -0,0 +1,81 @@
/* getservbyname.c - Service name-Port number conversion routine */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01b,31jul06,tkf Correct function description for apigen.
01a,27jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine getservbyname(), whcih
provides service structure depending on service name.
INCLUDE FILES: wrapper/wrapperHostLib.h
*/
/* includes */
#include <sys/socket.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
#include <wrapper/wrapperHostLib.h>
/* defines */
/* enums */
/* typedefs */
struct servent;
/* locals */
/*******************************************************************************
*
* getservbyname - provide service structure depending on service name (FTP, ...)
*
* This routine returns a structure servent of the specified service. The main
* field of interest in the servent structure is the port number. The port
* number is returned in network byte order.
*
* EXAMPLE
* \cs
* struct servent *pServ;
*
* pServ = getservbyname ("ftp", "tcp"); FTP using TCP
* pServ = getservbyname ("ftp", NULL); FTP using TCP
* \ce
*
* RETURNS
* Non-null pointer, if OK; or NULL, on error.
*
* ERRNO: N/A
*
* INCLUDE FILES
* This routine is only used within hostLib and not visible outside (private)
* hostLibInt.h (private header file for hostLib only)
*/
struct servent * getservbyname
(
const char * pName, /* service name, e.g., "ftp" */
const char * pProto /* "tcp" or "udp" */
)
{
return (struct servent *)ipcom_getservbyname (pName, pProto);
}
@@ -0,0 +1,80 @@
/* getservbyport.c - Port number-Service name conversion routine */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01b,31jul06,tkf Correct function description for apigen.
01a,27jul06,tkf Written.
*/
/*
DESCRIPTION
This module provides a backwards compatible routine getservbyport(), whcih
provides service structure depending on port nuumber.
INCLUDE FILES: wrapper/wrapperHostLib.h
*/
/* includes */
#include <sys/socket.h>
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <ipcom_sock2.h>
#include <wrapper/wrapperHostLib.h>
/* defines */
/* enums */
/* typedefs */
struct servent;
/* locals */
/*******************************************************************************
*
* getservbyport - provide service structure depending on port number (TCP, UDP)
*
* This routine accesses file services.c under VxWorks to return a structure
* servent of the specified service. The main field of interest in the servent
* structure is the service name.
*
* EXAMPLE
* \cs
* struct servent *pServ;
*
* pServ = getservbyport (htons(21), "tcp"); FTP using TCP
* pServ = getservbyport (htons(21), NULL); FTP using TCP
* \ce
*
* RETURNS
* Non-null pointer, if OK; or NULL, on error.
*
* ERRNO: N/A
*
* INCLUDE FILES
* This routine is only used within hostLib and not visible outside (private)
*/
struct servent * getservbyport
(
int port, /* port number */
char * pProto /* "tcp" or "udp" */
)
{
return (struct servent *)ipcom_getservbyport (port, pProto);
}
@@ -0,0 +1,169 @@
/* ifname.c - interface name lookup routines */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01b,20nov06,kch Added vxWorks.h and net/if.h include statements.
01a,12sep06,kch Written.
*/
/*
DESCRIPTION
This library provides backward-compatible interface name lookup routines
for if_nametoindex(), if_indextoname(), if_nameindex() and if_freenameindex().
The routines are now a wrapper implemented in terms of the preferred
ipcom_if_nametoindex(), ipcom_if_indextoname(), ipcom_if_nameindex() and
ipcom_if_freenameindex().
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <vxWorks.h>
#include <net/if.h>
#include <ipcom_vxworks.h>
#include <ipcom_sock.h>
#include <ipcom_err.h>
/******************************************************************************
*
* if_nametoindex - maps interface name to the interface index
*
* This routine maps the interface name to to the interface index.
*
* .IP <ifname>
* A null terminated interface name
*
* RETURNS: The interface index of the specified name or 0 if not found
*
* ERRNO: N/A
*
* NOMANUAL
*/
unsigned int if_nametoindex
(
const char *ifname
)
{
return (ifname == NULL ? 0 : ipcom_if_nametoindex (ifname));
}
/******************************************************************************
*
* if_indextoname - maps interface index into its corresponding name
*
* This routine maps an interface index into its corresponding name.
*
* .IP <ifindex>
* The index of the interface to get the name for.
*
* .IP <ifname>
* Pointer to a buffer of at least IF_NAMESIZE bytes.
*
* RETURNS: The pointer value of ifname or NULL
*
* ERRNO: N/A
*
* NOMANUAL
*/
char * if_indextoname
(
unsigned int ifindex,
char * ifname /* at least IF_NAMESIZE */
)
{
return ipcom_if_indextoname (ifindex, ifname);
}
/*****************************************************************************
*
* if_nameindex - Return interface array
*
* This routine returns an array of if_nameindex, one for each interface
* installed. The array ends with a entry with all fields set to 0.
*
* RETURNS: array of if_nameindex
*
* ERRNO: N/A
*
* NOMANUAL
*/
struct if_nameindex * if_nameindex
(
void
)
{
return (struct if_nameindex *)ipcom_if_nameindex();
}
/******************************************************************************
*
* if_freenameindex - Free interface array
*
* This routine free the array of if_nameindex returned from if_nameindex().
*
* ERRNO: N/A
*
* NOMANUAL
*/
void if_freenameindex
(
struct if_nameindex *pif
)
{
if (pif != NULL)
ipcom_if_freenameindex ((struct Ip_if_nameindex *)pif);
}
#ifdef TEST_IFNAME
#include <stdio.h>
#include <string.h>
STATUS testifname(void)
{
struct if_nameindex *iff = if_nameindex();
struct if_nameindex *ifx;
char ifname[IF_NAMESIZE+1];
unsigned int ifindex;
if (iff == NULL)
{
printf("testifname: No interface!\n");
return OK;
}
ifx = iff;
while (ifx->if_name != NULL)
{
printf("Got if_name <%s> if_index <%d>\n",
ifx->if_name, ifx->if_index);
printf("\tValidate if_nametoindex() wrapper...\n");
ifindex = if_nametoindex(ifx->if_name);
printf("\t\texpected <%d> got <%d>\n",
ifindex, ifx->if_index);
printf("\tValidate if_indextoname() wrapper...\n");
bzero(ifname, sizeof(ifname));
if_indextoname(ifx->if_index, ifname);
printf("\t\texpected <%s> got <%s>\n",
ifname, ifx->if_name);
ifx++;
}
if_freenameindex(iff);
return OK;
}
#endif /* TEST_IFNAME */
@@ -0,0 +1,393 @@
/* inetAddrLib.c - Internet address manipulation routines */
/*
* Copyright (c) 2006 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01j,07aug12,h_x Fix inetAddrTest after adapting ipcom_inet_addr() into inet_addr().
01i,25jul12,h_x Fix WIND00361943
01h,29sep10,h_x Fix build and coverity warnings.
01g,22jun10,h_x Fix WIND00219346
01f,12jun08,dlk Restore compatibility of inet_addr with VxWorks 6.4
behavior. Documentation corrections. Add disabled test cases.
01e,27mar08,nlu WIND00108893
01d,05mar08,uol Fixed WIND00116684: Add note that inet_aton() isn't
BSD-compatible
01c,15dec06,spw Added support for octal, hexidecimal addr representation
01b,01dec06,kch Corrected return code for inet_addr() and inet_aton().
01a,22aug06,kch Written.
*/
/*
DESCRIPTION
This library provides backward-compatible routines for inet_addr(),
inet_ntoa() and inet_aton() available in the previous releases of the
Wind River network stack. These routines are now wrappers implemented in
terms of the preferred routines ipcom_inet_addr(), ipcom_inet_ntoa() and
ipcom_inet_aton() respectively.
INCLUDE FILES: inetLib.h, inet.h
SEE ALSO: UNIX BSD 4.3 manual entry for inet(3N),
\tb "Wind River Network Stack for VxWorks 6, 3.1 Programmer's Guide"
*/
#include <vxWorks.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errnoLib.h>
#include <netinet/in.h>
#include <inetLib.h>
#include <ipcom_vxworks.h>
#include <ipcom_sock2.h>
/*******************************************************************************
*
* inet_addr - convert a dot notation Internet address to a long integer
*
* This routine interprets an Internet address string, returning the
* corresponding 32-bit value in network byte order, or returning
* (u_long)(-1) if the string is not a valid internet address string.
*
* This routine is obsolete; its return value does not distinguish
* between an error return and the valid 'all ones' restricted IPv4
* broadcast address 255.255.255.255. Instead of using this routine,
* use inet_aton() or inet_pton().
*
* This routine handles addresses of the forms
*
* \cs
* a a in [0, 4294967295UL]
* x = a
* a.b a in [0, 255]; b in [0, 16777215]
* x = (a << 24) + b
* a.b.c a, b in [0, 255]; c in [0, 65535]
* x = (a << 24) + (b << 16) + c
* a.b.c.d a, b, c, d in [0, 255]
* x = (a << 24) + (b << 16) + (c << 8) + d
* \ce
*
* where each of a, b, c, or d is a decimal, octal (starts with the
* digit 0) or hexidecimal (starts with 0x) number string; the corresponding
* numbers must be in the indicated ranges. Leading and embedded whitespace
* is not allowed, but any string character that is not a valid digit in the
* current numeric base other than '.' terminates any of the four forms,
* and additionally '.' will terminate the last form.
*
* The return value is x converted to network byte order if the address
* string is acceptable.
*
* EXAMPLE
* The following example returns 0x5a000002 on a big-endian target:
* \cs
* inet_addr ("90.0.0.2");
* \ce
*
* RETURNS: The Internet address, or (u_long)ERROR.
*
* ERRNO
* S_inetLib_ILLEGAL_INTERNET_ADDRESS
*
* SEE ALSO: inet_aton(), inet_pton().
*/
#if 0
uint32_t inet_addr
(
const char *s
)
{
uint32_t x = 0;
uint32_t val;
uint32_t max;
int shift;
unsigned base;
unsigned d;
int c;
const unsigned char * us = (const unsigned char *)s;
const unsigned char * t;
if (s == NULL)
goto errout;
if (strstr(s,":"))/*maybe a ipv6 addr,need return error*/
goto errout;
max = 0xffffffff;
for (shift = 24; ; shift -= 8, max >>= 8)
{
base = 10;
val = 0;
c = *us;
if (c == '0')
{
base = 8;
c = *++us;
if (c == 'x' || c == 'X')
{
base = 16;
c = *++us;
}
}
t = us;
while ((1))
{
if (base == 16)
{
if (!isxdigit (c))
break;
if (val >= 0x10000000)
goto errout;
if (isdigit (c))
d = (unsigned int)c - '0';
else if (isupper (c))
d = (unsigned int)c - 'A' + 10;
else
d = (unsigned int)c - 'a' + 10;
val = (val << 4) + d;
}
else
{
d = (unsigned int)c - '0';
if (d >= base) /* unsigned: also handles case 'c' < '0' */
break;
if (base == 8)
{
if (val >= 0x20000000)
goto errout;
val = (val << 3) + d;
}
else
{
if (val > 429496729 ||
(val == 429496729 && d > 5))
goto errout;
val = val * 10 + d;
}
}
c = *++us;
}
/* If we didn't consume any digits, it's an error */
if (t == us && base != 8)
goto errout;
if (c != '.' || shift == 0) /* got last number */
{
if (val > max)
goto errout;
x += val;
return htonl (x);
}
if (val > 255)
goto errout;
++us;
x += val << shift;
}
/* not reached */
errout:
errnoSet(S_inetLib_ILLEGAL_INTERNET_ADDRESS);
return (uint32_t)ERROR;
}
#else
uint32_t inet_addr (
const char *s
)
{
if(s == NULL)
return (uint32_t)ERROR;
return (uint32_t)ipcom_inet_addr(s);
}
#endif
#undef INET_ADDR_TEST
#ifdef INET_ADDR_TEST
typedef struct _INET_ADDR_CASE
{
char * s; /* Numeric internet address string */
Ip_u32 v; /* host byte order result of inet_addr (s) */
} INET_ADDR_CASE;
LOCAL INET_ADDR_CASE inet_addr_cases [] =
{
{NULL, ~0},
{"", ~0},
{".", ~0},
{"..", ~0},
{"0", 0},
{"0x", ~0},
{"0xz", ~0},
{"0x.", ~0},
{"4294967295", 0xffffffff},
{"0xff", 0xff},
{"0xff.", ~0},
{"0.", ~0},
{"00.", ~0},
{"071", 071},
{"0377", 0xff},
{"www.windriver.com", ~0},
{"0377.255", 0xff0000ff},
{"0xff.255.0377", 0xffff00ff},
{"1.0x2.03.", ~0},
{"1.0x2.03.4", 0x01020304},
{"0xab.cd.ef.01", ~0},
{"0xab.0xcd.0xef.0x01", 0xabcdef01},
{"0xab.0xcd.0xef.0x01.", 0xffffffff},
{"256.0.0.0", ~0},
{"-1.0.0.-1", ~0},
{"1.0378.0.0", 0xffffffff},
{"0.0.0x100.0", ~0},
{"0.0.0.0000000000000000000000000000000000000001", 1},
{"0.0.0.0x000000000000000000000000000000000000000100", ~0},
{"4294967296", ~0},
{"0x100000000", ~0},
{"037777777776", 0xfffffffe},
{"040000000000", ~0},
{"1.16777215", 0x01ffffff},
{"1.16777216", ~0},
{"1.1.65535", 0x0101ffff},
{"1.1.65536", ~0},
{"1.1.1.255", 0x010101ff},
{"1.1.1.256", ~0},
{"192.168.20.63", 0xc0a8143f},
{"255.255.255.255", 0xffffffff},
{"0.0.0.0", 0}
};
int inetAddrTest (void)
{
int i;
char * s;
uint32_t v;
uint32_t w;
int failures = 0;
for (i = 0; i < NELEMENTS(inet_addr_cases); ++i)
{
s = inet_addr_cases[i].s;
v = inet_addr_cases[i].v;
w = (uint32_t)inet_addr (s);
v = htonl (v);
if (w != v)
{
printf ("inet_addr(\"%s\") returns 0x%x; should be 0x%x\n",
s, w, v);
++failures;
}
}
return failures;
}
#endif /* INET_ADDR_TEST */
/*******************************************************************************
*
* inet_ntoa - convert a network address to dotted decimal notation
*
* This routine converts an Internet address in network format to dotted
* decimal notation.
*
* WARNING
* This routine is supplied for UNIX compatibility only. Previously, this
* routine allocates an 18 bytes of memory each time it is called and relies
* on the caller for the memory to be freed when done with the returned string.
* This is no longer the case with the current implementation. The string
* returned is a statically allocated buffer.
*
* This function is now implemented as a wrapper to ipcom_inet_ntoa(), which
* is implemented according to the standard. It is a well known built-in
* weakness of this function that it is not reentrant, hence, it is slowly
* being deprecated. To solve the reentrancy problem and also to support IPv6,
* the new function inet_ntop() was introduced and should be used instead
* whenever possible.
*
* EXAMPLE
* The following example returns a pointer to the string "90.0.0.2":
* \cs
* struct in_addr iaddr;
* ...
* iaddr.s_addr = htonl(0x5a000002);
* ...
* inet_ntoa (iaddr);
* \ce
*
* RETURNS: A pointer to the string version of an Internet address.
*
* SEE ALSO: inet_ntoa_b()
*/
char *inet_ntoa
(
struct in_addr inetAddress /* inet address */
)
{
struct Ip_in_addr *iaddr = (void *)&inetAddress;
return ipcom_inet_ntoa (*iaddr);
}
/*******************************************************************************
*
* inet_aton - convert a network address from dot notation, store in a structure
*
* This routine interprets an Internet address. All the network library
* routines call this routine to interpret entries in the data bases
* that are expected to be an address. The value returned is stored in
* network byte order in the structure provided.
*
* EXAMPLE
* On a big-endian target, the following example returns 0x5a000002 in
* the 's_addr' member of the structure pointed to by <pinetAddr>:
* \cs
* inet_aton ("90.0.0.2", pinetAddr);
* \ce
*
* RETURNS: OK, or ERROR if address is invalid.
*
* Note that the return code does not adhere to the BSD 4.4 specification.
*/
int inet_aton
(
const char * pString, /* string containing address, dot notation */
struct in_addr * inetAddress /* struct in which to store address */
)
{
int ret;
struct Ip_in_addr *addr = (struct Ip_in_addr *)inetAddress;
if (inetAddress == NULL)
return ERROR;
ret = ipcom_inet_aton (pString, addr);
if ( ret == 0)
{
errnoSet(IPCOM_ERRNO(ret));
return ERROR;
}
return OK;
}
@@ -0,0 +1,123 @@
/* inet_ntop.c - Internet address manipulation routine */
/*
* Copyright (c) 2006 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
modification history
--------------------
01b,01dec06,kch Sanity check for invalid arguments.
01a,22aug06,kch written.
*/
/*
DESCRIPTION
This library provides a backward compatible interface for inet_nton()
available in the previous releases of the Wind River network stack. This
routine is now a wrapper implemented in terms of the preferred routine
ipcom_inet_nton() which is available in the IPNet stack.
To use this feature, include the following component:
INCLUDE_INETLIB
INCLUDE FILES:
inetLib.h
*/
#include <ipcom_vxworks.h>
#include <ipcom_sock2.h>
#include <errnoLib.h>
const char * inet_ntop
(
int af, /* address family */
const void *src, /* pointer to numeric address */
char *dst, /* pointer to address string buffer */
size_t size /* size of allocated address string buffer */
);
/*******************************************************************************
*
* inet_ntop - convert a network format address to presentation format
*
* This routine converts an Internet address in network format to dotted
* decimal notation (IPv4) or hexadecimal notation (IPv6) respectively.
*
* This routine is identical to the UNIX inet_ntop() routine. A buffer dst
* of size INET_ADDRSTRLEN/INET6_ADDRSTRLEN must be provided. If size is
* too small to hold the resulting string, including the terminating '\0',
* a null pointer is returned and errno set to ENOSPC. If af is not
* supported, function returns an error with errno EAFNOSUPPORT.
*
* EXAMPLE
* The following example copies the string "90.0.0.2" to <dst>:
* \cs
* struct in_addr src;
* char dst[INET_ADDRSTRLEN];
* ...
* src.s_addr = 0x5a000002;
* ...
* inet_ntop (AF_INET, (void *) &src, dst, INET_ADDRSTRLEN);
* \ce
*
* The following example copies the string "FE80::2" to <dst>:
* \cs
* struct in6_addr src;
* char dst[INET6_ADDRSTRLEN];
* ...
* bzero ((char *) &src, sizeof (src));
* src.s6_addr[0] = 0xFE;
* src.s6_addr[1] = 0x80;
* src.s6_addr[15] = 0x02;
* ...
* inet_ntop (AF_INET6, (void *) &src, dst, INET6_ADDRSTRLEN);
* \ce
*
* RETURNS: pointer to dst or NULL on error
*
* ERRNO:
* ENOSPC
* EAFNOSUPPORT
* EINVAL
*/
const char * inet_ntop
(
int af, /* address family */
const void *src, /* pointer to numeric address */
char *dst, /* pointer to address string buffer */
size_t size /* size of allocated address string buffer */
)
{
if ((src == NULL) || (dst == NULL))
{
errnoSet (EINVAL);
return NULL;
}
return ipcom_inet_ntop (af, src, dst, size);
}
@@ -0,0 +1,122 @@
/* inet_pton.c - Internet address manipulation routine */
/*
* Copyright (c) 2006 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
modification history
--------------------
01b,01dec06,kch Sanity check for invalid arguments.
01a,22aug06,kch written.
*/
/*
DESCRIPTION
This library provides a backward compatible interface for inet_pton()
available in the previous releases of the Wind River network stack. This
routine is now a wrapper implemented in terms of the preferred routine
ipcom_inet_pton() which is available in the IPNet stack.
To use this feature, include the following component:
INCLUDE_INETLIB
INCLUDE FILES:
inetLib.h
*/
#if 0
static char rcsid[] = "$Id: inet_pton.c,v 1.2.16.1 2011-11-16 10:33:45 ulf Exp $";
#endif
#include <ipcom_vxworks.h>
#include <ipcom_sock2.h>
#include <errnoLib.h>
int inet_pton
(
int af,
const char *src,
void *dst
);
/*******************************************************************************
*
* inet_pton - convert a presentation format address to a network format address
*
* This routine converts an Internet address string in dotted decimal notation
* (IPv4) or hexadecimal notation (IPv6) respectively to network format.
*
* This routine is identical to the UNIX inet_pton() routine. If af is not
* supported, function returns an error with errno EAFNOSUPPORT.
*
* EXAMPLE
* The following example copies the numeric address of "90.0.0.2" to <dst>:
* \cs
* struct in_addr dst;
* char src[] = "90.0.0.2";
* ...
* inet_pton (AF_INET, src, (void *) &dst);
* \ce
*
* The following example copies the numeric address of "FE80::2" to <dst>:
* \cs
* struct in6_addr dst;
* char src[] = "FE80::2";
* ...
* inet_pton (AF_INET6, src, (void *) &dst);
* \ce
*
* RETURNS:
* \is
* \i 1 if the address was valid for the specified address family
* \i 0 if the address wasn't valid
* \i -1 if some other error occurred
* \ie
*
* ERRNO:
* EAFNOSUPPORT
* EINVAL
*/
int inet_pton
(
int af, /* address family */
const char *src, /* ASCII address string */
void *dst /* numeric address */
)
{
int ret;
if ((src == NULL) || (dst == NULL))
{
errnoSet (EINVAL);
return 0;
}
ret = ipcom_inet_pton (af, src, dst);
if (ret != 1)
errnoSet(IPCOM_ERRNO(ret));
return ret;
}
@@ -0,0 +1,387 @@
/* netSysctl.c - core sysctl init routines */
/*
* Copyright (c) 2006-2007 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.
*/
/*
modification history
--------------------
01d,05mar08,uol Fixed WIND00110881: Length of sysctl data is returned in the
oldidx field.
01c,01jun07,pad Replaced inclusion of sys/sysctl.h with private/sysctlP.h.
01b,11dec06,tkf Fix the problem of displaying multiple variables with
different OID prefixes during -a option.
01a,09dec06,tkf Writrten
*/
/*
DESCRIPTION
This module defines the handler routine for the IPNET sysctl mib tree.
The handler routine is a wrapper around the ipcom_sysctl() routine.
INCLUDE FILES: arpLib.h
SEE ALSO: inetLib
*/
/* includes */
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet_sysctl.h>
#include <ipnet.h>
#include <vxWorks.h>
#include <private/sysctlP.h> /* brings in sysctl_add_oid_internal() */
#include <ipcom_sysctl.h>
#include <sys/socket.h> /* for PF_ROUTE definition */
#include <memPartLib.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errnoLib.h>
/* defines */
/* enums */
/* typedefs */
/* locals */
/* imports */
SYSCTL_DECL_NODE_EXT(net);
int * ipcom_errno_get(void);
STATUS netSysctl
(
struct sysctl_oid * pOid,
void * pArg1,
int arg2,
struct sysctl_req * pReq
);
STATUS netSysctlCli
(
int argc,
char ** pArgv,
int nextLevelOid,
char * pOpts
);
STATUS netSysctlInit
(
BOOL foreign
);
/**************************************************************************
*
* netSysctl - network sysctl handler
*
* This is the registered handler routine for the IPNET sysctl mib tree. The
* routine is registered with the kernel sysctl if the _netSysctl function
* pointer pointd to it. The _netSysctl function pointer is assigned to
* netSysctl() when IPNET gets initialized if INCLUDE_NET_SYSCTL is defined.
*
* RETURNS: OK
*
* ERRNO: N/A
*
* NOMANUAL
*/
STATUS netSysctl
(
struct sysctl_oid * pOid,
void * pArg1,
int arg2,
struct sysctl_req * pReq
)
{
int * pName = (int *)pArg1;
int * pNewName;
STATUS status;
int errCode;
int i;
/* ipcom_sysctl expects to see the full OID array */
if ((pNewName = calloc ((size_t)arg2 + 1, sizeof(int))) == NULL)
{
#ifdef NETSYSCTL_DEBUG
printf ("netSysctl: memory allocation failed.\n");
#endif
errCode = ENOMEM;
goto exitErr;
}
pNewName [0] = CTL_NET;
for (i = 1; i < arg2 + 1; i++)
{
pNewName [i] = pName [i - 1];
}
status = OK;
errCode = 0;
if ((errCode = ipcom_sysctl (pNewName, (unsigned int)arg2 + 1,
(void *)pReq->oldptr,
(Ip_size_t *)&pReq->oldlen,
(void *)pReq->newptr,
(unsigned int)pReq->newlen)) == IPCOM_SUCCESS)
{
pReq->oldidx = pReq->oldlen;
goto exitOk;
}
/* Convert the IPCOM error code to VxWorks errno */
errCode = IPCOM_ERRNO(*(ipcom_errno_get()));
exitErr:
status = ERROR;
if (errCode)
errnoSet (errCode);
exitOk:
if (pNewName)
free (pNewName);
return status;
}
/**************************************************************************
*
* netSysctlCli - network sysctl CLI
*
* This routine interfaces the IPCOM sysctl CLI to the kernel sysctl CLI.
*
* RETURNS: OK
*
* ERRNO: N/A
*
* NOMANUAL
*/
STATUS netSysctlCli
(
int argc, /* If > 0, number of arguments */
char ** pArgv, /* If != NULL, pointer to arguments */
int nextLevelOid, /* if > 0, the OID of the next level node.
Valid only if pArgv[0] contains just the
top level network name ("net") */
char * pOpts
)
{
size_t i;
size_t j;
size_t nopts;
char ** pTmpArgv = NULL;
char optargs [2][3];
STATUS status;
int errCode;
Ipnet_cmd_sysctl * ipnetSysctlBase;
const Ipnet_cmd_sysctl * pNext;
char nlNodeName [32];
char * pC1;
BOOL addSetOpt = FALSE;
if (argc == 0)
{
#ifdef NETSYSCTL_DEBUG
printf ("netSysctlCli: Invalid input.\n");
#endif
errCode = ENOTSUP;
goto exitErr;
}
if ((ipnetSysctlBase = ipnet_sysctl_get_base ()) == NULL)
{
errCode = ENOTSUP;
#ifdef NETSYSCTL_DEBUG
printf ("netSysctlCli: could not get IPNET sysctl tree root.\n");
#endif
goto exitErr;
}
status = OK;
errCode = 0;
nopts = strlen (pOpts) / 2;
if ((strchr (*pArgv, '=') != NULL) &&
(strstr (pOpts, "-w") == NULL))
{
addSetOpt = TRUE;
nopts++;
}
pTmpArgv = calloc (nopts + (size_t)argc + 1, sizeof (char *));
if (pTmpArgv == NULL)
{
#ifdef NETSYSCTL_DEBUG
printf ("netSysctlCli: could not allocate memory.\n");
#endif
errCode = ENOMEM;
goto exitErr;
}
/* Obtain the option arguments */
i = 0;
pTmpArgv [i++] = "sysctl";
if (addSetOpt == TRUE)
pTmpArgv [i++] = "-w";
for (j = 0; j < nopts; j++)
{
size_t addedArgs = 1;
if (addSetOpt == TRUE)
addedArgs++;
/* Skip any options that we dont support */
if (strncmp (pOpts + 2 * j, "-a", 2) &&
strncmp (pOpts + 2 * j, "-w", 2))
continue;
strncpy (optargs [i - addedArgs], pOpts + 2 * j, 2);
optargs [i - addedArgs][2] = '\0';
pTmpArgv [i] = optargs [i - addedArgs];
i++;
}
/* Check if the passed object name or ID is what we expect */
nlNodeName [0] = 0;
if ((pC1 = strchr (pArgv [0], '.')))
{
int k = 1;
while ((*(pC1 + k) != '.') && (*(pC1 + k) != '\0'))
{
nlNodeName [k - 1] = pC1 [k];
k++;
}
nlNodeName [k -1] = 0;
}
for (pNext = ipnetSysctlBase->ntable; pNext->comp != IP_NULL; pNext++)
{
if (nlNodeName[0])
{
if (strcmp (nlNodeName, pNext->comp) == 0)
break;
}
else if (pNext->ctl [0] == nextLevelOid)
{
sprintf (nlNodeName, "%s.%s", pArgv[0], pNext->comp);
break;
}
}
if (pNext->comp == IP_NULL)
{
#ifdef NETSYSCTL_DEBUG
printf ("netSysctlCli: Invalid input.\n");
#endif
errCode = ENOTSUP;
goto exitErr;
}
/* Copy the arguments */
if (nextLevelOid)
{
/*
* We pass the constructed OID string. This situation is typically
* caused by Sysctl CLI when the IPNET sysctl tree is being accessed
* from the root as a result of the "-a" option.
*/
pTmpArgv [i++] = nlNodeName;
j = i;
}
else
{
for (j = i; j < (size_t)argc + i; j++)
pTmpArgv [j] = pArgv [j - i];
}
if ((errCode = ipnet_sysctl_common ((int)j, pTmpArgv)) == IPCOM_SUCCESS)
{
#ifdef NETSYSCTL_DEBUG
printf ("netSysctlCli: ipnet_cmd_sysctl failed.\n");
#endif
goto exitOk;
}
/* Convert the IPCOM error code to VxWorks errno */
errCode = IPCOM_ERRNO(*(ipcom_errno_get()));
exitErr:
status = ERROR;
if (errCode)
errnoSet (errCode);
exitOk:
if (pTmpArgv)
free (pTmpArgv);
return status;
}
/**************************************************************************
*
* netSysctlInit - Initiailize IPNET sysctl to work with vxWorks sysctl
*
* This routine initializes the IPNET sysctl to work with the kernel sysctl.
* The routine registers the IPNET top level nodes to the kernel sysctl tree.
*
* RETURNS: OK or ERROR if initialization fails.
*
* ERRNO: N/A
*
* NOMANUAL
*/
STATUS netSysctlInit
(
BOOL foreign
)
{
Ipnet_cmd_sysctl * ipnetSysctlBase;
const Ipnet_cmd_sysctl * pNext;
int nodeFlags;
int i;
nodeFlags = CTLFLAG_RW | CTLTYPE_NODE;
/* Get the IPNET sysctl base table */
if ((ipnetSysctlBase = ipnet_sysctl_get_base ()) == NULL)
{
#ifdef NETSYSCTL_DEBUG
printf ("netCoreSysctlInit: could not get IPNET sysctl tree root.\n");
#endif
return ERROR;
}
if (foreign == TRUE)
nodeFlags |= CTLFLAG_FOREIGN;
/* We register as a foreign node */
for (i=0, pNext = ipnetSysctlBase->ntable; pNext->comp != IP_NULL; pNext++)
{
struct sysctl_oid * pIpnetNodes;
pIpnetNodes = SYSCTL_ADD_NODE(pNetSysctlCtxList, \
SYSCTL_NODE_CHILDREN(net), \
pNext->ctl [0], pNext->comp, \
nodeFlags, netSysctl, \
pNext->comp);
if (pIpnetNodes == NULL)
{
#ifdef NETSYSCTL_DEBUG
printf ("netCoreSysctlInit: SYSCTL_ADD_NODE failed for \"net.%s\"\n",
pNext->comp);
#endif
return ERROR;
}
}
return OK;
}
@@ -0,0 +1,132 @@
/* sntpcLib.c - Simple Network Time Protocol (SNTP) client wrappers */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01c,10dec10,rjq Update SNTP timer resolution from milliseconds to nanoseconds.
01b,25jun08,mca Changed timeout interval in sntpcTimeGet() to ticks.
(WIND00124830)
01a,07nov06,kch Written.
*/
/*
DESCRIPTION
This library provides backward-compatible sntpcTimeGet() routine to retrieve
the current time from a remote source. The routine is now a wrapper implemented
in term of the preferred ipsntp_query_time().
*/
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipcom_time.h>
#include <errnoLib.h>
#include <sntpcLib.h>
/* Directory structure different in vxWorks21.03 so must redeclare the SNTP version here */
#define SNTP_VERSION_1 ((Ip_u8)1) /* oldest version number */
#define SNTP_VERSION ((Ip_u8)4) /* current version number */
#define SNTP_PORT 123
/* defines */
IMPORT IP_PUBLIC Ip_err ipsntp_wait_time(char *maddr, char *ifname,
Ip_u16 port, Ip_s32 tmo,
struct Ip_timespec *sntp_time,
Ip_u8 version);
IMPORT Ip_err ipsntp_query_time(const char *server, Ip_u16 port,
Ip_s32 tmo, struct Ip_timespec *sntp_time,
Ip_u8 version);
IMPORT int sysClkRateGet (void);
/*******************************************************************************
*
* sntpcTimeGet - retrieve the current time from a remote source
*
* This routine stores the current time as reported by an SNTP/NTP server in
* the location indicated by <pCurrTime>. The reported time is first converted
* to the elapsed time since January 1, 1970, 00:00, GMT, which is the base value
* used by UNIX systems. If <pServerAddr> is NULL, the routine listens for
* messages sent by an SNTP/NTP server in broadcast (mulitcast in case of IPv6)
* mode. Otherwise, this routine sends a request to the specified SNTP/NTP
* server and extracts the reported time from the reply. In either case, an
* error is returned if no message is received within the interval specified
* by <timeout>. Typically, SNTP/NTP servers operating in broadcast (mulitcast
* in case of IPv6) mode send update messages every 64 to 1024 seconds. An
* infinite timeout value is specified by WAIT_FOREVER.
*
* RETURNS: OK, or ERROR if unsuccessful.
*
* ERRNO:
* S_sntpcLib_INVALID_PARAMETER, S_sntpcLib_INVALID_ADDRESS, S_sntpcLib_TIMEOUT,
* S_sntpcLib_SERVER_UNSYNC, S_sntpcLib_VERSION_UNSUPPORTED
*/
STATUS sntpcTimeGet
(
char * pServerAddr, /* server IP address or hostname */
int timeout, /* timeout interval in ticks */
struct timespec * pCurrTime /* storage for retrieved time value */
)
{
Ip_err ret;
struct Ip_timespec tv;
if ((pCurrTime == NULL) ||
((((int)timeout) < 0) && (((int)timeout) != WAIT_FOREVER)))
{
errnoSet (S_sntpcLib_INVALID_PARAMETER);
return (ERROR);
}
/* Convert ticks to seconds */
if (timeout > 0)
{
if (timeout < sysClkRateGet())
timeout = 1;
else if (timeout % sysClkRateGet() < sysClkRateGet() / 2)
timeout = timeout / sysClkRateGet();
else
timeout = timeout / sysClkRateGet() + 1;
}
if (pServerAddr == NULL)
ret = ipsntp_wait_time (NULL, NULL, SNTP_PORT, timeout, &tv, SNTP_VERSION_1);
else
ret = ipsntp_query_time (pServerAddr, SNTP_PORT, timeout, &tv, SNTP_VERSION_1);
switch (ret)
{
case IPCOM_SUCCESS:
pCurrTime->tv_sec = (time_t)tv.tv_sec;
pCurrTime->tv_nsec = tv.tv_nsec;
break;
case IPCOM_ERR_FAILED:
case IPCOM_ERR_INVALID_ARG:
errnoSet (S_sntpcLib_INVALID_PARAMETER);
return ERROR;
case IPCOM_ERR_TIMEOUT:
errnoSet (S_sntpcLib_TIMEOUT);
return ERROR;
default:
return ERROR;
}
return OK;
}
@@ -0,0 +1,275 @@
/* sntpsLib.c - Simple Network Time Protocol (SNTP) server wrappers */
/*
* Copyright (c) 2009-2013 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.
*/
/*
modification history
--------------------
01c,13sep13,rjq Fix for WIND00431901.
01b,10dec10,rjq Update SNTP timer resolution from milliseconds to nanoseconds
01a,13oct09,rjq Written.
*/
/*
DESCRIPTION
This library provides backward-compatible sntpsClockSet() routine to
assign a routine to access the reference clock. Also the sntpsNsecToFraction()
routine is provided to convert portions of a second to NTP format.
*/
/* includes */
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipcom_ipd.h>
#include <ipcom_sysvar.h>
#include <ipcom_time.h>
#include <errnoLib.h>
#include <sntpsLib.h>
IMPORT IP_PUBLIC Ip_u32 ipsntp_client_fraction_to_nsec(Ip_u32 fraction);
IMPORT IP_PUBLIC Ip_u32 ipsntp_server_nsec_to_fraction(Ip_u32 nsecs);
IMPORT IP_PUBLIC void ipsntp_register_server_time_hook(int (*servtime)(Ip_u32 *, Ip_u32 *));
IMPORT IP_PUBLIC void ipsntp_set_reference(struct Ip_timespec *ref_time, Ip_u32 ref_id);
IMPORT IP_PUBLIC void ipsntp_set_precision(Ip_s32 precision);
LOCAL FUNCPTR ipsntpsClockHookRtn = NULL; /* Access to timestamp information. */
#define NSEC_BASE2 30 /* Integral log2 for nanosecond conversion. */
/* 1970 - 1900 in seconds */
#define SNTPS_JAN_1970 2208988800UL
/* NTP fragments to microseconds: 1/sec * x * 10^-6 sec * 2^32 */
#define SNTPS_MICROFRAC 4295L
/*******************************************************************************
*
* ipsntpsGetTime - use new ClockHook to get time
*
* This routine use the new interface the customer's defined to get ntptime.
*
* RETURNS: OK or ERROR.
*
* ERRNO: N/A
*/
int ipsntpsGetTime(Ip_u32 *sec, Ip_u32 *frac)
{
SNTP_TIMESTAMP ntptime;
int result;
if(NULL == ipsntpsClockHookRtn)
{
errnoSet (S_sntpsLib_INVALID_PARAMETER);
return (ERROR);
}
result = (ipsntpsClockHookRtn)(IPSNTPS_TIME, &ntptime);
if(result == ERROR) /* time is not available. Use default value. */
{
*sec = 0;
*frac = 0;
}
else
{
*sec = (Ip_u32)ntptime.seconds;
*frac = (Ip_u32)ntptime.fraction;
}
return result;
}
/*******************************************************************************
*
* sntpsLog2Get - find approximate power of two
*
* This routine determines the nearest integral power of two for the given
* value, without using floating point arithmetic. It is used to convert
* 32-bit nanosecond values into signed integers for assignment to the poll
* and precision fields of NTP messages.
*
* RETURNS: Nearest integral log base two value, in host byte order.
*
* ERRNO: N/A
*
* INTERNAL
* Floating-point calculations can't be used because some boards (notably
* the SPARC architectures) disable software floating point by default to
* speed up context switching. These boards abort with an exception when
* floating point operations are encountered.
*
* NOMANUAL
*/
IP_STATIC char sntpsLog2Get
(
Ip_u32 inval /* input value for calculation */
)
{
int loop;
int floor; /* Nearest power of two for smaller value */
int limit; /* Nearest power of two for larger value */
int result;
Ip_u32 mask; /* Bitmask for log2 calculation */
if (inval == 0)
result = 0;
else
{
/*
* Set increasing numbers of the low-order bits of the input value
* to zero until all bits have been cleared. The current and previous
* values of the loop counter indicate the adjacent integral powers
* of two.
*/
for (loop = 0; loop < 32; loop ++)
{
mask = (Ip_u32)(~0 << loop); /* Mask out the rightmost "loop" bits. */
if ( (inval & mask) == 0)
break;
}
floor = 1 << (loop - 1);
limit = 1 << loop;
if (inval - (Ip_u32)floor < (Ip_u32)limit - inval)
result = loop - 1;
else
result = loop;
}
return ((char)result);
}
/*******************************************************************************
*
* sntpsClockSet - assign a routine to access the reference clock
*
* This routine installs a hook routine that is called to access the
* reference clock used by the SNTP server. This hook routine must use the
* following interface:
* .CS
* STATUS sntpsClockHook (int request, void *pBuffer);
* .CE
* The hook routine should copy one of three settings used by the server to
* construct outgoing NTP messages into <pBuffer> according to the value of
* the <request> parameter. If the requested setting is available, the
* installed routine should return OK (or ERROR otherwise).
*
* This routine calls the given hook routine with the <request> parameter
* set to SNTPS_ID to get the 32-bit reference identifier in the format
* specified in RFC 1769. It also calls the hook routine with <request>
* set to SNTPS_RESOLUTION to retrieve a 32-bit value containing the clock
* resolution in nanoseconds. That value will be used to determine the 8-bit
* signed integer indicating the clock precision (according to the format
* specified in RFC 1769). Other library routines will set the <request>
* parameter to SNTPS_TIME to retrieve the current 64-bit NTP timestamp
* from <pBuffer> in host byte order. The routine sntpsNsecToFraction() will
* convert a value in nanoseconds to the format required for the NTP
* fractional part.
*
* RETURNS: OK or ERROR.
*
* ERRNO: N/A
*/
STATUS sntpsClockSet
(
FUNCPTR pClockHookRtn /* new interface to reference clock */
)
{
Ip_u32 id;
Ip_u32 resolution;
Ip_s32 precision;
struct Ip_timespec time;
SNTP_TIMESTAMP ntptime;
STATUS result;
if(pClockHookRtn == NULL)
return (ERROR);
result = (*pClockHookRtn) (IPSNTPS_TIME, &ntptime);
if(result == ERROR) /* time is not available. Use default value. */
{
time.tv_sec = 0;
time.tv_nsec = 0;
}
else
{
/* The current 64-bit NTP timestamp from ntptime is in host byte order */
time.tv_sec = (Ip_time_t)(ntptime.seconds - SNTPS_JAN_1970);
time.tv_nsec = (long)ipsntp_client_fraction_to_nsec((Ip_u32)ntptime.fraction);
}
result = (*pClockHookRtn) (IPSNTPS_ID, &id);
if(result == ERROR) /* Clock ID is not available. Use default value. */
id = 0;
/* set reference identifier */
ipsntp_set_reference(&time, id);
result = (*pClockHookRtn) (IPSNTPS_RESOLUTION, &resolution);
if (result == ERROR)
precision = 0;
else
{
/* Find nearest power of two to clock resolution.
* Convert to seconds required for NTP message. Subtract nearest
* integer to log base two of 1E9 (corresponds to division of clock
* resolution by 1E9).
*/
precision = (Ip_s32)(sntpsLog2Get(resolution) - NSEC_BASE2);
}
/* set resolution */
ipsntp_set_precision(precision);
/* register server time hook */
ipsntpsClockHookRtn = pClockHookRtn;
ipsntp_register_server_time_hook(ipsntpsGetTime);
return (OK);
}
/*******************************************************************************
*
* sntpsNsecToFraction - convert portions of a second to NTP format
*
* This routine is provided for convenience in fulfilling an SNTPS_TIME request
* to the clock hook. It converts a value in nanoseconds to the fractional part
* of the NTP timestamp format. The routine is not designed to convert
* non-normalized values greater than or equal to one second. Although the NTP
* time format provides a precision of about 200 pico-seconds, rounding errors
* in the conversion process decrease the accuracy as the input value increases.
* In the worst case, only the 24 most significant bits are valid, which reduces
* the precision to tenths of a micro-second.
*
* RETURNS: Value for NTP fractional part in host-byte order.
*
* ERRNO: N/A
*
* INTERNAL
* Floating-point calculations can't be used because some boards (notably
* the SPARC architectures) disable software floating point by default to
* speed up context switching. These boards abort with an exception when
* floating point operations are encountered.
*/
ULONG sntpsNsecToFraction
(
ULONG nsecs /* nanoseconds to convert to binary fraction */
)
{
return ipsntp_server_nsec_to_fraction((Ip_u32)nsecs);
}
@@ -0,0 +1,139 @@
/* ifShow.c - Interface display routines */
/*
* Copyright (c) 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.
*/
/*
modification history
--------------------
01a,20nov08,ggz Created.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for ifShow() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper which encapsulates calls to routine ipnet_cmd_ifconfig()
in the IPNet stack.
This library provides routines to show various interface-related
information.
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void ifShow
(
char *ifName /* name of the interface to show */
);
/*******************************************************************************
*
* ifShow - display the attached network interfaces
*
* This routine displays the attached network interfaces for debugging and
* diagnostic purposes. If <ifName> is given, only that interface is displayed.
* If <ifName> is omitted, all attached interfaces are displayed.
*
* For each interface selected, the following are shown: Internet
* address, point-to-point peer address (if using SLIP), broadcast address,
* netmask, subnet mask, Ethernet address, route metric, maximum transfer
* unit, number of packets sent and received on this interface, number of
* input and output errors, and flags (such as loopback, point-to-point,
* broadcast, promiscuous, ARP, running, and debug).
*
* EXAMPLE:
* The following call displays all interfaces (such as "ln0", "ln1", and "ln2"):
* .CS
* -> ifShow
* .CE
* The following call displays just the interface "ln0":
* .CS
* -> ifShow "ln0"
* .CE
*
* RETURNS: N/A
*
*
* INTERNAL
* When using the Tornado shell, this routine is only available if an
* "@" sign is prepended to the routine name. Otherwise, it is preempted
* by a built-in version.
*/
void ifShow
(
char *ifName /* name of the interface to show */
)
{
int argc;
int errCode = 0;
#define IFCONFIG_MAXARGS 2
char * tempArgv[IFCONFIG_MAXARGS + 2];
char ** argv = tempArgv;
char * newifName=0;
size_t alen=0;
if (ifName != NULL) /* if a name was specified */
{
alen=strlen(ifName)+1;
if ((newifName = calloc (1, alen))==NULL)
{
errCode = ENOMEM;
goto exitErr;
}
bzero(newifName,alen);
strcpy(newifName,ifName);
if (getOptServ(newifName, "ifconfig", &argc, argv,
IFCONFIG_MAXARGS + 2) != OK)
{
errCode = ENOMEM;
goto exitErr;
}
}
else
{
argv[0] = "ifconfig";
argv[1] = "-a";
argc = 2;
}
if ((errCode = ipnet_cmd_ifconfig (argc, argv)) == IPCOM_SUCCESS)
goto exitOk;
/* Convert the IPCOM error code to VxWorks errno */
errCode = IPCOM_ERRNO(errCode);
exitErr:
if (errCode)
errnoSet (errCode);
exitOk:
if (newifName != NULL)
free (newifName);
return;
}
@@ -0,0 +1,360 @@
/* ifconfig.c - routines for network interface configuration */
/*
* Copyright (c) 2006-2007 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.
*/
/*
modification history
--------------------
01f,15sep10,xhs support IPLITE
01e,11jul07,kch Doc update: change command to set vlan user priority bits
from 'upriority' to 'vlanpri'.
01d,22aug06,kch Updated doc and removed unneeded semaphore protection.
01c,04aug06,tlu Added promisc mode to comment block
01b,19jul06,tkf Improve command descriptions.
01a,14jul06,tkf Written.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for ifconfig() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper implemented in terms of the preferred routine ipnet_cmd_ifconfig()
which is available in the IPNet stack.
ifconfig() is a function that you can use to configure a network interface or
retrieve its configuration parameters.
INCLUDE FILES: net/utils/ifconfig.h
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int ifconfig
(
char *pString /* A string of command options. */
);
/******************************************************************************
*
* ifconfig - set or get configuration values for a network interface
*
* Use ifconfig() to configure a network interface or to retrieve network
* interface configuration values. The API of ifconfig() is oriented towards
* command line use, but it can be used programmatically. The valid 'ifconfig'
* command line syntax for assigning information to a network interface is
* as follows:
* \ss
* ifconfig "<interface> [<protocol>] [<parameter> <parameterValue>]"
* \se
* For example:
* \ss
* ifconfig "fei0 inet6 add 3ffe:1::1111"
* \se
* This ifconfig() call assigns 3ffe:1::1111 as the IPv6 address for fei0.
* This call could also have been made less explicitly as:
* \ss
* ifconfig "fei0 inet6 3ffe:1::1111"
* \se
* As a convenience, failing to specify a <parameter> value before the address
* is interpreted as indicating the default, 'add'. Similarly, because of a
* prejudice in favor of IPv4, failure to specify a <protocol> value is
* interpreted as indicating the default of 'inet', IPv4.
*
* The valid 'ifconfig' command line syntax for retrieving information on a
* network interface is as follows:
* \ss
* ifconfig "[<flags>] [<interface>] [<protocol>]"
* \se
* The valid combinations of option <flags> when using 'ifconfig' to generate
* reports are as follows:
* \ss
* ifconfig "[-L] <interface> [<protocol>]"
* ifconfig "-a [-L] [-d] [-u] [<protocol>]"
* ifconfig "-l [-d] [-u] [<protocol>]"
* ifconfig "[-L] [-d] [-u]"
* \se
* The correct usage of the elements of an ifconfig() call is as follows:
* \is
* \i <flags>
* The <flags> values apply in report-generating ifconfig() calls. Use 'a'
* instead of specifying an <interface> value if you want a report containing
* information on all interfaces. Use 'd' to limit the report to down
* interfaces. Use 'l' to limit the report to a simple list of all interfaces
* without additional information. Use 'L' to request lifetime information on
* an IPv6 address presented as a time offset string. Use 'u' to limit the
* report to up interfaces.
* \i <interface>
* This element in an ifconfig() call lets you specify the name of the network
* interface to which the command applies. The generic format of a network
* interface name is <UnitnameUnitnumber>, which results in names such as fei0.
* \i <protocol>
* This element lets you specify the network protocol associated with the call.
* The default <protocol> value is 'inet', which indicates the IPv4 protocol.
* The other valid value for <protocol> under WindNet is 'inet6'.
* \i <address>
* If the <protocol> is 'inet', the <address> is either a host name already
* present in the host name database (see hosts()), or an IPv4 Internet address
* expressed in Internet standard dot notation. You can also use the CIDR
* notation (also known as the slash notation) to specify netmask with the
* address. For example, using CIDR (slash) notation, 192.168.0.1/16 is a
* possible 'inet' <address> string. However, if the protocol is 'inet6',
* the slash in an <address> string is interpreted as an indicator of the prefix
* length. For example, ::1/128. If you do not use slash notation to specify a
* prefix length in an 'inet6' <address>, 'ifconfig' assumes a default value of
* 64. To override this default without using the slash notation, you can use
* the 'prefixlen' parameter. See the entry under the <parameters> description
* for more information.
* \i <destAddr>
* This element of an ifconfig() call appears only when the call applies to
* the local end of a point-to-point link. In this case, the <destAddr> value
* indicates the address of the correspondent on the other end the link. See
* the 'add' entry under the <parameters> description below.
* \i <parameters>
* These elements of an ifconfig() call let you set the value of the
* configuration parameters associated with a network interface. See the
* descriptions provided below for 'add', and all the other
* <parameters> values supported under WindNet.
* \ie
* The following is a list of valid values for <parameters>.
* \is
* \i 'add'
* Add another network address to this interface. You may want to use this
* parameter when changing network numbers. It leaves the old address in
* place, which allows the interface to still accept packets destined
* to the old address. If the new address is on the same subnet as the first
* network address for this interface, you must specify a netmask of 0xffffffff.
* If this 'add' applies to the local end of a point-to-point connection, you
* need to include the other end's destination address. The syntax is:
* \ss
* 'ifconfig' "<protocol> 'add' <address> <destAddr>"
* \se
* Note that the equivalent command 'alias' is currently not supported.
*
* \i 'delete'
* Remove the network address specified.
* \i anycast
* Specify that the IPv6 address configured is an anycast address. Based on
* the current specification, only routers may configure anycast addresses.
* Anycast address will not be used as source address of any of outgoing IPv6
* packets.
*
* Note that the equivalent commands '-alias' and 'remove' are not currently
* not supported.
*
* \i 'down'
* Mark an interface "down". If an interface is marked "down", IP does
* not transmit through that interface. If possible, 'ifconfig' "<interface>
* 'down'" also disables packet reception on the specified <interface>.
* \i create
* Create the specified network pseudo-device. If the interface is given
* without a unit number, try to create a new device with an arbitrary unit
* number. If creation of an arbitrary device is successful, the new device
* name is printed to standard output.
* \i destroy
* Destroy the specified network pseudo-device.
* \i 'mtu' <n>
* Set the maximum transmission unit (MTU) of the interface to <n>. The
* default MTU value is interface specific and may not be configurable.
* \i 'preferred'
* Set the preferred lifetime for the specified IPv6 address.
* \i 'prefixlen' <length>
* This <parameters> value is valid only when <protocol> is 'inet6'. The
* <length> value specifies the number of address bits used for dividing
* networks into subnets. The <length> must be an integer value between 0
* and 128. It is usually 64 under the current IPv6 assignment rule.
* If the 'prefixlen' is omitted, a default value of 64 is assumed. You can
* also use the "slash after the address" notation to specify the prefix
* length.
* \i 'tentative'
* Set the tentative bit in the specified IPv6 address.
* \i '-tentative'
* Clear the tentative bit in the specified IPv6 address.
* \i 'up'
* Mark an interface as "up". Use this <parameters> value to undo a previous
* 'ifconfig' "<interface> 'down'" call. This status change is a software event
* only. Simply marking an interface as up cannot reinitialize the hardware
* associated with that interface.
* \i 'valid'
* Set the valid lifetime for the specified IPv6 address.
* \i 'dstaddr'
* Set remote address to 'a' (inet and PPP only).
* \i 'lladdr' <addr>
* Set interface link address to <addr>.
* \i 'vr' <vr>
* Set virtual router to <vr>
* \i 'dhcp'
* Enable dhcp auto configuration (inet only).
* \i '-dhcp'
* Disable dhcp auto configuration (inet only).
* \i 'link'
* Enable special processing at the link level.
* \i '-link'
* Disable special processing at the link level..
* \i 'promisc'
* Enable promisc mode at the interface
* \i '-promisc'
* Disable promisc mode at the interface
* \ie
*
* WRAPPER CHANGES:
*
* The ifconfig backwards compatibility wrapper routine does not support (or
* supports it differently for) the following parameters:
*
* \ts
* Command Name | Alternative | Description
* ---------------|-------------|------------
* alias | add | Add inet6 or inet addresses
* -alias | delete | Remove inet6 or inet addresses
* remove | delete | Remove inet6 or inet addresses
* arp | None | Enable the Address Resolution Protocol on the
* | | specified network interface.
* -arp | None | Disable the Address Resolution Protocol on the
* | | specified network interface.
* autoconf | None | Enable IPv6 auto configuration for the specified
* | | interface.
* -autoconf | None | Disable IPv6 auto configuration for the specified
* | | interface.
* broadcast | None | specify the address used to broadcast to the
* | | network (inet only).
* debug | None | Enable driver dependent debugging code.
* -debug | None | Disable driver dependent debugging code.
* deprecated | None | Set the IPv6 deprecated address bit.
* -deprecated | None | Clear the IPv6 deprecated address bit.
* media type | None | Set the media type of the interface
* mediaopt opts | None | Set media options of the interface
* vlan vlan_tag | None | Set the VLAN ID of the interface (1-4094).
* vlanpri value | None | Set the VLAN User Priority (0-7).
* vlandev iface | None | Associate a physical interface to a VLAN pseudo
* | | interface.
* -vlandev iface | None | Disassociate physical interface from a VLAN
* | | pseudo interface.
* metric | None | Set the routing metric for the interface.
* pltime | preferred | preferred lifetime for the specified IPv6
* | | address
* -tentative | None | Clear the tentative bit in the specified IPv6
* | | address.
* vltime | valid | Set the valid lifetime for the specified IPv6
* | | address.
* dstaddr | different | Set PPP remote address (inet only)
* | | Part of the 'add' parameter.
* -------------------------------------------------------------------------------
* \te
*
* WRAPPER UNSUPPORTED:
*
* The following flags (used for report generating ifconfig calls) are not
* supported:
*
* \ts
* Flag | Alternative | Description
* ---------------+-------------+------------
* -d | None | Limit report to 'down' interfaces.
* -L | None | request lifetime information on an IPv6 address
* | | presented as a time offset string.
* -l | None | limit the report to a simple list of all
* | | interfaces without additional information.
* -u | None | limit the report to 'up' interfaces.
* \te
*
* WRAPPER NEW:
*
* The following are new commands (from IPNET):
*
* \ts
* Command | Alternative | Description
* ---------------+-------------+------------
* lladdr <addr> | New | Set interface link address to <addr>.
* vr <vr> | New | Set virtual router to <vr>
* dhcp | New | Enable dhcp auto configuration (inet only).
* -dhcp | New | Disable dhcp auto configuration (inet only)
* link[0-2] | New | Enable special processing at the link level.
* -link[0-2] | New | Disable special processing at the link level.
* \te
*
* RETURNS: OK, or ERROR
*
* ERRNO: N/A
*
* SEE ALSO
* netstat()
*
*/
int ifconfig
(
char *pString /* A string of command options. */
)
{
int argc;
int errCode = 0;
#define IFCONFIG_MAXARGS 50
char * tempArgv[IFCONFIG_MAXARGS + 2];
char ** argv = tempArgv;
char * newString=0;
size_t alen=0;
STATUS status = OK;
if (pString != NULL)
{
alen=strlen(pString)+1;
if ((newString = calloc (1, alen))==NULL)
{
errCode = ENOMEM;
goto exitErr;
}
bzero(newString,alen);
strcpy(newString,pString);
if (getOptServ(newString, "ifconfig", &argc, argv,
IFCONFIG_MAXARGS + 2) != OK)
{
errCode = ENOMEM;
goto exitErr;
}
}
else
{
argv[0] = "ifconfig";
argv[1] = "-a";
argc = 2;
}
#if _WRS_CONFIG_COMPONENT_IPLITE
if ((errCode = iplite_cmd_ifconfig_common (argc, argv)) == IPCOM_SUCCESS)
#else
if ((errCode = ipnet_cmd_ifconfig_common (argc, argv)) == IPCOM_SUCCESS)
#endif
goto exitOk;
/* Convert the IPCOM error code to VxWorks errno */
errCode = IPCOM_ERRNO(errCode);
exitErr:
status = ERROR;
if (errCode)
errnoSet (errCode);
exitOk:
if (newString != NULL)
free (newString);
return status;
}
@@ -0,0 +1,229 @@
/* ipProto.c - documentation for routines retained from ipProto.c */
/*
* Copyright (c) 2007 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01e,19apr08,dlk Fix '==' typo in ipDetach().
01d,10may07,kch Fixed to make ipAttach() and ipDetach() available
unconditionally.
01c,24apr07,tkf Add IPv6-Only build support.
01b,13sep06,dlk Add support for ipDetach() and ip6Detach().
01a,07jul06,dlk Written.
*/
/*
DESCRIPTION
This library provides a backwards-compatible interface between the IP protocol
stack and the MUX for both NPT and END devices. The ipAttach() and ip6Attach()
routines bind all supported network-layer protocols built into the Wind River
network stack to a specific END or NPT device. These routines are wrappers
implemented in terms of the preferred routine ipcom_drv_eth_init() from
ipcom_drv_eth.c.
BEHAVIOR CHANGES
In previous releases of the Wind River network stack, ipAttach() attached
only IPv4 and ARP protocols to the device, while ip6Attach() attached only
IPv6. In the current release, these routines behave identically and attach
all supported network-layer protocols built into the stack at archive-build
time.
Similarly, in previous releases, ipDetach() would detach only IPv4 and
ARP from the device, while ip6Detach() would detach only IPv6. In the
current stack, ipDetach() and ip6Detach() behave identically, and detach
all supported network-layer protocols from the stack.
To avoid a new error when calling both ipDetach() and ip6Detach()
on the same interface, these routines have been modified to return
OK if the specified END interface exists but is not attached to the stack.
Without this change, the first detach call would completely detach the END,
and the second detach call would get an error.
INCLUDE FILES: ipProto.h
*/
/* includes */
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <muxLib.h>
#include <ipcom_err.h>
#include <ipcom_clib.h>
#include <ipcom_sock.h>
#include <ipProto.h>
#include <errnoLib.h>
#include <string.h>
#include <stdio.h>
#include <muxLib.h>
/******************************************************************************
*
* ipAttach - a generic attach routine for the IPv4 network stack
*
* This routine takes the unit number and device name of an END or NPT
* driver (e.g., (0, "ln") for interface "ln0", etc.) and attaches all
* supported network-layer protocols built into the stack to the
* specified network interface. This routine behaves identically to
* ip6Attach().
*
* The IPCOM interface name (which may be different from the END
* interface name) is chosen as the next available interface name
* of the form "ethX" where X is replaced with a decimal number
* indicating the IPCOM interface unit number.
*
* If the END device has already been attached to IPCOM, the routine
* returns successfully without doing anything.
*
* RETURNS: OK or ERROR
* ERRNO: An M_ipcom errno with the ipcom error value in the low order 16 bits
*/
int ipAttach
(
int unit, /* Unit number */
char *name /* Device name (e.g. "ln", "ei", etc.). */
)
{
Ip_err stat = ipcom_drv_eth_init(name, (Ip_u32)unit, IP_NULL);
if (stat == IPCOM_SUCCESS)
return OK;
errnoSet (IPCOM_ERRNO(stat)); /* What if ipcom set its own errno? */
return ERROR;
}
/*******************************************************************************
*
* ipDetach - The detach routine for the TCP/IP network stack
*
* This routine removes the TCP/IP stack from the MUX. If completed
* successfully, protocols will no longer receive packets
* from the named END driver.
*
* This routine behaves identically to ip6Detach().
*
* RETURNS: OK or ERROR
*/
STATUS ipDetach
(
int unit, /* Unit number */
char *pDevice /* Device name (i.e. ln, ei etc.). */
)
{
Ip_fd fd;
struct Ip_ifreq ifr;
int ret;
const char * ifname;
END_OBJ * pEnd;
memset (&ifr, 0, sizeof (ifr));
pEnd = endFindByName (pDevice, unit);
if (pEnd == NULL ||
snprintf (ifr.ifr_name, IP_IFNAMSIZ, "%s%d", pDevice, unit)
>= IP_IFNAMSIZ)
{
errnoSet (S_muxLib_NO_DEVICE);
return ERROR;
}
/*
* In case the interface was attached with ipcom_drv_eth_init()
* using a name different than the END name, we map the END interface
* name to the ipnet interface name.
*/
if ((ifname = ipcom_get_ip_if_name (ifr.ifr_name)) == IP_NULL)
{
/* Already detached, return OK */
return OK;
}
strncpy (ifr.ifr_name, ifname, IP_IFNAMSIZ);
ip_assert (ifr.ifr_name[IP_IFNAMSIZ - 1] == '\0');
fd = ipcom_socket (IP_AF_INET, IP_SOCK_RAW, 0);
if (fd < 0 && (fd = ipcom_socket (IP_AF_INET6, IP_SOCK_RAW, 0)) < 0)
return ERROR;
/* we must bring the interface down before detaching */
ret = ipcom_socketioctl (fd, IP_SIOCGIFFLAGS, &ifr);
if (ret == 0)
{
ifr.ip_ifr_flags &= (Ip_u16)~IP_IFF_UP;
ret = ipcom_socketioctl (fd, IP_SIOCSIFFLAGS, &ifr);
}
if (ret == 0)
ret = ipcom_socketioctl (fd, IP_SIOCXDETACH, &ifr);
(void)ipcom_socketclose (fd);
return (ret);
}
#ifdef INET6
/******************************************************************************
*
* ip6Attach - a generic attach routine for the IPv6 network stack
*
* This routine takes the unit number and device name of an END or NPT
* driver (e.g., (0, "ln") for interface "ln0", etc.) and attaches all
* supported network-layer protocols built into the stack to the
* specified network interface. This routine behaves identically to
* ipAttach().
*
* The IPCOM interface name (which may be different from the END
* interface name) is chosen as the next available interface name
* of the form "ethX" where X is replaced with a decimal number
* indicating the IPCOM interface unit number.
*
* If the END device has already been attached to IPCOM, the routine
* returns successfully without doing anything.
*
* RETURNS: OK or ERROR
* ERRNO: An M_ipcom errno with the ipcom error value in the low order 16 bits
*/
int ip6Attach
(
int unit, /* Unit number */
char *name /* Device name (e.g. "ln", "ei", etc.). */
)
{
return ipAttach (unit, name);
}
/*******************************************************************************
*
* ip6Detach - The detach routine for the IPv6 TCP/IP network stack
*
* This routine removes the IPv6 TCP/IP stack from the MUX. If completed
* successfully, protocols will no longer receive packets
* from the named END driver.
*
* This routine behaves identically to ipDetach().
*
* RETURNS: OK or ERROR
*/
STATUS ip6Detach
(
int unit, /* Unit number */
char *pDevice /* Device name (i.e. ln, ei etc.). */
)
{
return ipDetach (unit, pDevice);
}
#endif /* INET6 */
@@ -0,0 +1,276 @@
/* netstat.c - network information display routines */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01c,15sep10,xhs support IPLITE
01b,22aug06,kch Fixed warning and minor doc update.
01a,27jul06,kch Written.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for netstat() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper implemented in terms of the preferred routine ipnet_cmd_netstat()
which is available in the IPNet stack.
INCLUDE FILES: net/utils/netstat.h
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <net/utils/netstat.h>
#define NETSTAT_MAXARGS 50
/*******************************************************************************
*
* netstat - show network status
*
* Use netstat() to print a representation of the contents of the various
* network-related data structures. The output varies in content and format
* depending on the option flags you select. The netstat() API is oriented
* towards command-line use, but you can use it programmatically. The valid
* command-line syntax is as follows:
*
* All arguments must be quoted strings: e.g., netstat "-a"
*
* \ss
* netstat -h
* netstat [-an] [-f address_family] [-V vr] [-p protocol]
* netstat -r [-nl] [-f address_family] [-V vr]
* netstat -s [raw|ip|icmp|sctp|udp|tcp|ip6|icmp6]
* \se
*
* Interpret the option flags as follows:
* \is
* \i '-a'
* Show the state of all sockets except those associated with server processes.
* If used with '-r', this option also shows the protocol-generated routes
* (routes generated by an RTF_PRCLONING parent route). Normally, these routes
* are not shown.
* \i '-f' <address_family>
* Use this option flag to limit statistics or address control block reports
* to those of the specified address family. The following address families
* are recognized: 'inet', for AF_INET; and 'inet6', for AF_INET6.
* \i '-n'
* Show network addresses as numbers (normally netstat() interprets addresses
* and attempts to display them symbolically).
* \i '-p' <protocol>
* Limit the reported statistics to those of the protocol specified by
* <protocol>.
* \ts
* <Protocol> | Address Family
* -----------------------------------------------------------------------
* 'icmp' | Valid for '-f inet' only.
* 'igmp' | Valid for '-f inet' only.
* 'ip' | Valid for '-f inet' only.
* 'pim' | Valid for '-f inet' only.
* 'tcp' | Valid for both '-f inet' and '-f inet6'.
* 'udp' | Valid for both '-f inet' and '-f inet6'.
* 'sctp' | Valid for both '-f inet' and '-f inet6'.
* 'icmp6' | Valid for '-f inet6' only.
* 'ip6' | Valid for '-f inet6' only.
* 'rip6' | Valid for '-f inet6' only.
* 'comp' | Valid for '-f unix' only.
* \te
* A null response does not necessarily indicate failure. Usually it means
* that there are no interesting numbers to report. The netstat() call
* will complain if the <protocol> is unknown or if the protocol implementation
* does not support a statistics routine.
* \i '-r'
* Show the routing tables. When '-s' is also present, show the routing
* statistics instead.
* \ie
* \sh Output Display Formats
* The default display for active sockets shows the local and remote
* addresses, send and receive queue sizes (in bytes), protocol, and the
* internal state of the protocol. Address formats are of the form
* "host.port" or "network.port" if a socket address specifies a network
* but no specific host address. When known, the host and network addresses
* are displayed symbolically. If a symbolic name for an address is unknown,
* or if you specify the '-n' option, the address is printed numerically,
* according to the address family. Unspecified, or "wild-card", addresses
* and ports appear as "*".
*
* The routing table display indicates the available routes and their status.
* Each route consists of a destination host or network and a gateway to use
* when forwarding packets. The 'flags' field shows information on the route
* stored as binary choices. The mapping between letters and flags is:
* \ts
* Letter | Flag | Description
* -------+---------------+--------------------------------------------------
* 1 | RTF_PROTO2 | Protocol specific routing flag #1
* 2 | RTF_PROTO1 | Protocol specific routing flag #2
* B | RTF_BLACKHOLE | Just discard packets (during updates)
* b | RTF_BROADCAST | The route represents a broadcast address.
* C | RTF_CLONING | Generate new routes on use.
* c | RTF_PRCLONING | Protocol-specified generate new routes on use.
* D | RTF_DYNAMIC | Created dynamically (by redirect).
* G | RTF_GATEWAY | Destination requires forwarding by intermediary.
* H | RTF_HOST | Host entry (net otherwise).
* L | RTF_LLINFO | Valid protocol to link address translation.
* M | RTF_MODIFIED | Modified dynamically (by redirect).
* R | RTF_REJECT | Host or net unreachable.
* S | RTF_STATIC | Manually added.
* U | RTF_UP | Route usable.
* W | RTF_WASCLONED | Route was generated as a result of cloning.
* X | RTF_XRESOLVE | External daemon translates protocol to link address.
* \te
* Direct routes are created for each interface attached to the local host.
* The gateway field for such entries shows the address of the outgoing
* interface. The 'refcnt' field gives the current number of active uses of
* the route. Connection-oriented protocols normally hold on to a single
* route for the duration of a connection while connectionless protocols
* obtain a route while sending to the same destination. The 'use' field
* provides a count of the number of packets sent using that route. The MTU
* entry shows the MTU associated with that route. This MTU value is used as
* the basis for the TCP maximum segment size. An 'L' flag appended to the
* MTU value indicates that the value is locked and that path MTU discovery is
* turned off for that route. A "-" indicates that the MTU for this route
* has not been set, and a default TCP maximum segment size will be used.
*
* FUNCTIONAL CHANGES:
*
* The following describes the behavior changes of the netstat() functionalities
* that are available in previous release of the Wind River network stack.
*
* The following option flags are interpreted differently:
* \is
* \i '-f'
* The following address families are no longer recognized: 'unix' for AF_LOCAL;
* and 'link' for AF_LINK.
* \i Previously this option flag prints full IPv6 addresses. It is now
* interpreted as "Do not show routes where the LLINFO flag is set.".
* \ie
*
* NEW OPTIONS:
*
* The following are the new <options> that have been added:
* \ts
* Option | Description
* -------------+---------------------------------------------------------------
* '-h' | Help, this usage menu
* '-V' <vr> | Specify virtual router index. 0 if not specified.
* '-T' <table> | Specify route table ID. 0 if not specified.
* '-l' | Do not show routes where the LLINFO flag is set.
* '-P' | Show which process that owns the socket.
* '-s' | Display networking statistics.
* -------------+---------------------------------------------------------------
* \te
*
* UNSUPPORTED OPTIONS:
*
* The following <options> are no longer supported:
* \ts
* Option | Description
* -------+-------------------------------------------------------------------
* '-A' | Show the address of any protocol control blocks associated
* | with sockets.
* '-b' | With the interface display (option '-i' , as described below),
* | show the number of bytes in and out.
* '-d' | With either interface display (option '-i' or an interval, as
* | described below), show the number of dropped packets.
* '-g' | Show information related to multicast (group address) routing.
* | By default, show the IP Multicast virtual-interface and routing
* | tables. If the '-s' option is also present, show multicast routing
* | statistics.
* '-I' | Show information about the specified interface; used with a wait
* | interval as described below.
* '-i' | Show the state of interfaces which have been auto-configured
* | (interfaces statically configured into a system, but not located
* | at boot time are not shown). If the '-a' option is also present,
* | multicast addresses currently in use are shown for each Ethernet
* | interface and for each IP interface address. Multicast addresses
* | are shown on separate lines following the interface address with
* | which they are associated.
* '-L' | Show the size of the various listen queues. The first count shows
* | the number of unaccepted connections. The second count shows the
* | number of unaccepted incomplete connections. The third count shows
* | the maximum number of queued connections.
* '-s' | Show per-protocol statistics. If this option is repeated, counters
* | with a value of zero are suppressed.
* '-t' | Display the contents of the interface watchdog timers.
* '-W' | Do not truncate addresses even if this causes some fields to
* | overflow.
* '-w' | Show network interface statistics at intervals of <wait> seconds.
*--------+--------------------------------------------------------------------
* \te
*
* RETURNS: OK, or ERROR
*
* ERRNO: N/A
*/
STATUS netstat
(
char *paramString /* a string of command options. */
)
{
int argc;
char *tempArgv [NETSTAT_MAXARGS + 2];
char *newString = NULL;
char **argv = tempArgv;
int ret = OK;
size_t alen=0;
if (paramString == NULL)
{
argv[0] = "netstat";
argc = 1;
goto cmd;
}
alen = strlen (paramString) + 1;
if ((newString = calloc (1, alen))==NULL)
{
printf("netstat: calloc failed\n");
return ERROR;
}
strcpy (newString,paramString);
ret = getOptServ (newString, "netstat", &argc, argv, NETSTAT_MAXARGS + 2);
if (ret != OK)
{
printf ("Too many arguments.\n");
errnoSet(EINVAL);
goto done;
}
cmd:
#if _WRS_CONFIG_COMPONENT_IPLITE
if ((ret = iplite_cmd_netstat (argc, argv)) == IPCOM_SUCCESS)
#else
if ((ret = ipnet_cmd_netstat (argc, argv)) == IPCOM_SUCCESS)
#endif
{
ret = OK;
goto done;
}
/* Convert the IPCOM error code to VxWorks errno */
errnoSet(IPCOM_ERRNO(ret));
ret = ERROR;
done:
if (newString)
free (newString);
return ret;
}
@@ -0,0 +1,267 @@
/* ping6Lib.c - Packet InterNet Grouper (PING) library for IPv6 */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01f,15sep10,xhs support IPLITE
01e,05jan07,spw Remove redundant debug statement, clean up docs.
01d,06dec06,spw Clean up documentation of '-t' option. Do not allow
numPackets argument to be zero (backwards compatibility)
01c,03aug06,kch Fixed ping6() to allow invocation with no argument. Also
updated doc.
01b,02aug06,kch Fixed warning.
01a,27jul06,kch Written.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for ping6() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper implemented in terms of the preferred routine ipnet_cmd_ping6()
which is available in the IPNet stack. And component INCLUDE_IPWRAP_PING6
has strict dependency on INCLUDE_SHELL.
The routine ping6() is typically called from the VxWorks shell to check the
network connection to another VxWorks target or to a UNIX host. ping6()
may also be used programmatically by applications that require such a test.
The remote host must be running TCP/IP networking code that responds to
ICMP6 echo request packets.
CAVEATS: It is not safe to interrupt the VxWorks shell using Ctrl-C while
the shell is executing ping6() in the kernel; doing so will leak memory and
sockets.
INCLUDE FILES: ping6Lib.h
*/
#ifndef IPCOM_USE_INET6
#define IPCOM_USE_INET6
#endif
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipcom_clib.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
/* defines */
#define PING6_MAXARGS 50
#ifdef _WRS_KERNEL
STATUS ping6
(
char *host, /* parameters plus host address */
int numPackets /* number of packets to receive */
);
/*******************************************************************************
*
* ping6 - send ICMPv6 ECHO_REQUEST packets to network hosts
*
* This routine tests that a remote host is reachable by sending ICMP6
* echo request packets, and waiting for replies. It may called from
* the VxWorks shell as follows:
* \cs
* -> ping6 "[options] remoteSystem [remoteSystem2 ...]" [, <numPackets>]
* \ce
* where <remoteSystem> is a host name and [options] are the following:
*
* \ts
* -c <count> | Stop after sending count ECHO_RESPONSE packets.
* -F <label> | Specifcy the flow label in the IPv6 header.
* -h <hoplimit> | Set the IPv6 hoplimit.
* -I <ifname> | Forces the packet to be sent on the specified interface.
* -m <ifname> | Name of outgoing interface for multicast addresses.
* -N <addr> | Uses 'addr' as the first-hop node.
* -n | Numeric output only. No attempts will be made to look up
* | names for host addresses.
* -Q <tclass> | Specify the traffic class in the IPv6 header.
* -r | Bypass the normal routing tables and send directly to a host on
* | an attached network.
* -S <src_addr> | Specifies the address to use a source address when sending.
* -s <packetsize> | Specifies the number of data bytes to be sent. The default is
* | 56, which translates into 64 ICMP data bytes when combined with
* | the 8 bytes of ICMP header data.
* -T <Prefer> | temporary addresses as source.
* -V <vr> | Specify virtual router. vr = 0 if not specified.
* -w <timeout> | Timeout in milliseconds, default is 1000 ms.
* hop ... Zero or more nodes that the echo request must pass,
* in order, before reaching the final host node
* -silent | no output, returns success or failure.
* \te
*
* If non-zero, the \<numPackets\> argument specifies a packet count, which
* is used only if the '-c \<count\> argument is not specified. The
* \<numPackets\> argument is available only in the kernel, and
* must be passed when calling ping6() programmatically in the kernel.
*
* If more than one remote system is listed, the echo requests will be
* loose source-routed along the specified path.
*
* FUNCTIONAL CHANGES:
*
* The following describes the behavior changes of the ping6() functionalities
* that are available in previous release of the Wind River network stack.
*
* NUMBER OF PACKETS RECEIVED:
*
* Previously, ping6 assumes a packet count of 1 if no packet count argument is
* specified using the \<numPackets\> argument or '-c \<count\>' option. This
* is now changed such that ping6 will stop after 4 echoed packets are
* received.
*
* OPTIONS CHANGES:
*
* The following option flags are interpreted differently:
* \is
* \i '-w'
* Previously this option flag means "generate an ICMPv6 Node Information FQDN
* query rather than an echo request". It is now interpreted as "Timeout in
* milliseconds, default is 1000 ms ". The systax is '-w \<timeout\>.
* \ie
*
* NEW OPTIONS:
*
* The following are the new <options> that have been added:
* \ts
* Option | Description
* ----------------+------------------------------------------------------------
* '-F' <label> | Specifcy the flow label in the IPv6 header.
* '-Q' <tclass> | Specify the traffic class in the IPv6 header.
* '-r' | Bypass the normal routing tables and send directly to a
* | host on an attached network.
* '-V' <vr> | Specify virtual router. vr = 0 if not specified.
* '-w' <timeout> | Timeout in milliseconds, default is 1000 ms.
* -------------+---------------------------------------------------------------
* \te
*
* UNSUPPORTED OPTIONS:
*
* The following <options> are no longer supported:
* \ts
* Option | Description
* --------------+--------------------------------------------------------------
* '-a' [aclsgA] | Generate ICMPv6 Node Information Note Addresses query rather
* | than echo-request.
* '-b' <size> | Set socket buffer size.
* '-d' | Set the SO_DEBUG option.
* '-f' | Flood ping. Outputs packets as fast as they come back, or
* | 50 times per second, whichever is faster.
* '-g' <gateway>| Specify <gateway> as the next-hop to the destination node.
* '-H' | Try reverse-lookup of IPv6 addresses. Opposite of -n.
* '-i' <wait> | Wait <wait> milliseconds between sending each packet
* '-l' <preload>| Send <preload> packets without delay the start of the run.
* '-m' | Do not fragment unicast packet to minimum IPv6 MTU. If
* | given more than once, do not fragment multicast to minimum
* | MTU either.
* '-N' | Probe the Node Information multicast group for the specified
* | host name. The <remoteSystem> must be a host name, not a
* | numeric IPv6 address, and -I <ifname> must be specified.
* '-p' <hexpat> | Hexadecimal byte fill pattern, e.g. 0123abadcafe4567
* '-q' | Quiet output. Only header and summary lines are displayed.
* '-v' | Verbose output.
* '-W' | Same as -w, but using old packet format based on revision
* | 03 draft.
* --------------+--------------------------------------------------------------
* \te
*
* RTP SUPPORT:
*
* Running ping6 as an RTP executable from the 'cmd' shell is currently not
* supported.
*
* RETURNS:
*
* OK, or ERROR if the remote host is not reachable or some other error
* occurred.
*
* ERRNO: N/A
*
*/
STATUS ping6
(
char *host, /* parameters plus host address */
int numPackets /* number of packets to receive */
)
{
char * args = NULL;
size_t len;
Ip_err ret = OK;
int argc;
char *tempArgv [PING6_MAXARGS + 2]; /* ugly */
char **argv = tempArgv;
if (numPackets < 0)
{
printf("ping6: Invalid arguments\n");
errnoSet (EINVAL);
return ERROR;
}
if (host == NULL) /* let ipnet_cmd_ping6() prints the usage */
{
argv[0] = "ping6";
argc = 1;
goto cmd;
}
len = strlen (host) + 24; /* enough for added "-c4000111222 " */
args = calloc (1, len);
if (args == NULL)
{
printf("ping6: calloc failed\n");
errnoSet (ENOMEM);
return ERROR;
}
if (numPackets != 0)
sprintf (args, "-c%d %s", numPackets, host);
else
strcpy (args, host);
ret = getOptServ (args, "ping6", &argc, argv, PING6_MAXARGS + 2);
if (ret == ERROR)
{
printf("ping6:too many arguments.");
errnoSet(EINVAL);
goto done;
}
cmd:
#if _WRS_CONFIG_COMPONENT_IPLITE
if ((ret = iplite_cmd_ping6 (argc, argv)) == IPCOM_SUCCESS)
#else
if ((ret = ipnet_cmd_ping6 (argc, argv)) == IPCOM_SUCCESS)
#endif
{
ret = OK;
goto done;
}
/* Convert the IPCOM error code to VxWorks errno */
errnoSet(IPCOM_ERRNO(ret));
ret = ERROR;
done:
if (args)
free (args); /* XXX - clean-up if the user does Ctrl-C? */
return ret;
}
#endif /* _WRS_KERNEL */
@@ -0,0 +1,810 @@
/* pingLib.c - Packet InterNet Grouper (PING) library */
/*
* Copyright (c) 2006-2007, 2010-2011, 2013-2014, 2018
* Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
18feb18,dlk Use at most one task delete hook (VXW6-86678)
22may14,qsn Fix VXW6-82648
16jul13,rjq Detach INLCUDE_PING from INCLUDE_SHELL
26dec11,h_x Fix WIND00291926
05may11,rjq Fix ping crash for WIND00266351 and WIND00271721.
21sep10,sic Added "-silent" to options list
15sep10,xhs support IPLITE
05jan07,spw Fix continuous ping documentation
19dec06,spw Added support for octal, hex ip address notation.
Return error for negative numPackets argument.
Return error on ping timeout.
06dec06,spw Clean up documentation of -t option. Do not allow
numPackets argument to be zero (backwards compatibility)
22aug06,kch Fixed warning and minor doc update.
03aug06,kch Do not apply the -t option if numPackets is not specified.
03aug06,kch Modified ping() to handle invocation with no argument.
03aug06,kch Written.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for ping() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper implemented in terms of the preferred routine ipnet_cmd_ping()
which is available in the IPNet stack.
The routine ping() is typically called from the VxWorks shell to check the
network connection to another VxWorks target or to a UNIX host. ping()
may also be used programmatically by applications that require such a test.
The remote host must be running TCP/IP networking code that responds to
ICMP echo request packets. The ping() routine is re-entrant, thus may
be called by many tasks concurrently.
INCLUDE FILES: pingLib.h
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipcom_clib.h>
#include <ipnet.h>
#include <ipcom_list.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <inetLib.h>
#include <strutil.h>
#include <semLib.h>
#include <taskLib.h>
#include <taskHookLib.h>
#include <private/jobLibP.h> /* for jobAdd() */
#include <pingLib.h>
/* globals */
#define PING_MAXARGS 50
typedef struct ping_session_entry
{
Ipcom_list entry;
WIND_TCB * shellTcb; /* task calling ping() */
Ip_bool shellTaskDone;
Ip_bool pingTaskDone;
int stop; /* ping task stop flag */
int pingRet; /* return value for ping() */
int pingErr; /* errno value for ping() */
int argc;
char * argv [PING_MAXARGS + 2]; /* +2 for command name and NULL */
} PING_SESSION;
enum ping_session_player
{
PING_SESSION_SHELL_TASK = 1,
PING_SESSION_PING_TASK = 2
};
static Ipcom_once_t ping_init_once;
static SEM_ID ping_sessions_mutex;
static Ipcom_list ping_sessions;
int _pingTxLen = 64; /* size of icmp echo packet */
int _pingTxTmo = PING_TMO; /* packet timeout in seconds */
#if _WRS_CONFIG_COMPONENT_IPLITE
IMPORT int iplite_cmd_ping(int argc, char **argv);
#define ipnet_cmd_ping_stoppable(a, b, c) iplite_cmd_ping(a, b)
#else
IMPORT int ipnet_cmd_ping_stoppable(int argc, char **argv, int *stop);
#endif
static void ping_delete_hook(WIND_TCB * pTcb);
/***************************************************************************
*
* ping_session_release - release a ping session
*
* This function releases the ping session <pSession>. Both the
* original task running ping(), and the spawned task that runs pingtask(),
* must release the session before it may be removed from the ping
* session list and freed.
*
* The spawned pingtask() task calls this routine with second argument
* PING_SESSION_PING_TASK before returning, and the original task calling
* ping() calls this function with second argument PING_SESSION_SHELL_TASK
* if a ping session is registered (and if the original task is not deleted or
* restarted). In case the original task is deleted before it calls
* ping_session_release(), the deletion hook marks the session to indicate
* that the original "shell" task has released it, so that the session will
* be removed and freed when the pingtask() task releases it.
*
* RETURNS: N/A
* ERRNO: N/A
* \NOMANUAL
*/
static void
ping_session_release(PING_SESSION * pSession, enum ping_session_player caller)
{
Ip_bool remove = IP_FALSE;
(void) semTake (ping_sessions_mutex, WAIT_FOREVER);
switch (caller)
{
case PING_SESSION_SHELL_TASK:
pSession->shellTaskDone = IP_TRUE;
remove = pSession->pingTaskDone;
break;
case PING_SESSION_PING_TASK:
pSession->pingTaskDone = IP_TRUE;
remove = pSession->shellTaskDone;
break;
default:
break;
}
if (remove)
{
ipcom_list_remove (&pSession->entry);
if (ipcom_list_length (&ping_sessions) == 0)
{
if (taskDeleteHookDelete((FUNCPTR)ping_delete_hook) != OK)
{
printErr("Error deleting ping deletion hook!\n");
}
}
}
(void) semGive (ping_sessions_mutex);
/* caller still holds task deletion safety */
if (remove)
{
free (pSession);
}
}
/***************************************************************************
*
* ping_delete_hook_remove_job - jobAdd job to remove deletion hook
*
* Since the task deletion hook may not itself call taskDeleteHookDelete(),
* it instead posts this function as a jobAdd() job to remove the ping
* deletion hook.
*
* RETURNS: N/A
* ERRNO: N/A
* \NOMANUAL
*/
static void ping_delete_hook_remove_job(_Vx_usr_arg_t arg1,
_Vx_usr_arg_t arg2,
_Vx_usr_arg_t arg3,
_Vx_usr_arg_t arg4,
_Vx_usr_arg_t arg5,
_Vx_usr_arg_t arg6)
{
(void) arg1; (void) arg2; (void) arg3;
(void) arg4; (void) arg5; (void) arg6;
if (taskDeleteHookDelete((FUNCPTR)ping_delete_hook) != OK)
{
printErr("Error deleting ping deletion hook in job!\n");
}
}
/***************************************************************************
*
* ping_delete_hook - ping task deletion hook
*
* This function is a task deletion hook that is installed whenever there
* is at least one ping session in progress, and removed when all current
* ping sessions are done.
*
* This hook handles the case that the task calling ping() is deleted
* while waiting for the spawned ping command to complete. For instance,
* this may commonly occur if the user calls ping() from the kernel shell
* and uses Ctrl-C to restart the shell while the ping() command is still
* running.
*
* The deletion hook checks if <pTcb> corresponds to the task that
* called ping() for one of the current ongoing ping sessions. If
* so, it sets a flag in the session that will cause ipnet_ping_cmd_stoppable()
* to stop pinging.
*
* The deletion hook also marks the ping session to indicate that the
* task that called ping() has released the session. If the spawned
* pingtask() task has also released the session, the session is removed
* from the session list and freed. If it was the last session,
* a job is posted to remove the deletion hook.
*
* RETURNS: N/A
* ERRNO: N/A
* \NOMANUAL
*/
static void
ping_delete_hook(WIND_TCB * pTcb)
{
PING_SESSION * pSession;
Ip_u32 count = 1;
(void) semTake (ping_sessions_mutex, WAIT_FOREVER);
for (pSession = IPCOM_LIST_FIRST(&ping_sessions);
pSession != IP_NULL;
pSession = IPCOM_LIST_NEXT(&pSession->entry))
{
if (pTcb == pSession->shellTcb)
{
if (pSession->stop == IPNET_PING_CMD_PINGING)
pSession->stop = IPNET_PING_CMD_REQUEST_STOP;
pSession->shellTaskDone = IP_TRUE;
pSession->shellTcb = NULL;
if (pSession->pingTaskDone)
{
ipcom_list_remove (&pSession->entry);
count = ipcom_list_length(&ping_sessions);
}
else
{
pSession = NULL;
}
break;
}
}
(void) semGive (ping_sessions_mutex);
if (pSession != NULL)
{
free (pSession);
/*
* If this was the last session, we want to remove
* the task deletion hook.
*
* We currently cannot call taskDeleteHookDelete()
* from within a task deletion hook (it will hang).
* Instead, post taskDeleteHookDelete() to the
* exception or job task.
* Note, it is possible that another ping session
* comes into existence before the job task runs;
* for that brief period, there may be two instances
* of the ping_delete_hook() in the task delete hook
* table; but that will not hurt.
*/
if (count == 0 &&
jobAdd(ping_delete_hook_remove_job, 0, 0, 0, 0, 0, 0) != OK)
{
printErr ("jobAdd(ping_delete_hookRemoveJob,...) failed\n");
}
}
}
/***************************************************************************
*
* pingtask - ping helper task
*
* Calls to ping() spawn this helper task, in case the task that calls
* ping() is deleted or restarted (e.g., if it is the shell task and the
* user types Ctrl-C). This task makes the actual calls to the ipnet
* ping command, using information in <pSession>. This function holds
* task deletion safety while it executes. It returns when the ipnet
* ping command returns, which may occur if the task calling ping()
* is terminated, in which case ping_delete_hook() sets a flag
* (pSession->stop) to indicate that the ipnet ping command should
* stop pinging.
*
* Before returning, this function sets the ping return and errno
* information in <pSession>, and sets <pSession->stop>
* to IPNET_PING_CMD_NO_PING_IN_PROGRESS. It calls ping_session_release()
* to release <pSession>, freeing it if the original task calling
* ping has also released it (or the deletion hook has run).
*
* RETURNS: N/A
* ERRNO: N/A
* \NOMANUAL
*/
static void
pingtask(PING_SESSION * pSession)
{
int ret;
/*
* In principle, this task can be successfully spawned,
* but deleted by some other task before calling taskSafe().
* But this should be unlikely. (An option to start a task
* deletion-safe might be useful...)
*/
(void) taskSafe();
ret = ipnet_cmd_ping_stoppable(pSession->argc,
pSession->argv,
&pSession->stop);
if (ret == IPCOM_SUCCESS)
{
/*
* IPnet ping returns SUCCESS even if we timed out.
* Return ERROR for timeout for backwards compatibility.
*/
if (*(ipcom_errno_get()) == IP_ERRNO_ETIMEDOUT)
{
pSession->pingErr = ETIMEDOUT;
ret = ERROR;
}
}
else
{
/* Convert the IPCOM error code to VxWorks errno */
pSession->pingErr = IPCOM_ERRNO(ret);
ret = ERROR;
}
pSession->pingRet = ret;
VX_MEM_BARRIER_W();
pSession->stop = IPNET_PING_CMD_NO_PING_IN_PROGRESS;
ping_session_release(pSession, PING_SESSION_PING_TASK);
(void)taskUnsafe();
}
/***************************************************************************
*
* ping_lib_init - ping library init routine
*
* Init the global ping_sessions list and pingLib mutex
*
* RETURNS: N/A
* ERRNO: N/A
* \NOMANUAL
*/
static Ip_err
ping_lib_init(void *ignored)
{
(void)ignored;
ipcom_list_init (&ping_sessions);
ping_sessions_mutex = semMCreate (SEM_Q_PRIORITY |
SEM_INVERSION_SAFE |
SEM_DELETE_SAFE);
if (ping_sessions_mutex == NULL)
return IPCOM_ERR_FAILED;
return IPCOM_SUCCESS;
}
/*******************************************************************************
*
* ping - test that a remote host is reachable
*
* This routine tests that a remote host is reachable by sending ICMP
* echo request packets, and waiting for replies. It may called from
* the VxWorks shell as follows:
* .CS
* -> ping "[options] remoteSystem", [<numPackets>],[<flags>]
* .CE
* where <remoteSystem> is either a host name that has been previously added
* to the remote host table, or an Internet address in dot notation (for
* example, "90.0.0.2"). See the FUNCTIONAL CHANGES section below for more
* information about the availability of the [options].
*
* The second parameter, \<numPackets\>, specifies the number of ICMP packets
* to receive from the remote host. The \<numPackets\> argument is used only
* if the -c \<count\> argument is not specified. See the FUNCTIONAL CHANGES
* section below for more information.
*
* The following \<flags\> parameters are maintained for backward
* compatibility:
* \is
* \i PING_OPT_SILENT
* Suppress output. This option is useful for applications that use ping()
* programmatically to examine the return status.
* \i PING_OPT_DONTROUTE
* Do not route packets past the local network. This also prevents pinging
* local addresses (i.e. the IP address of the host itself). The 127.x.x.x
* addresses will still work however. This option is functionally equivalent
* to the '-r' command option. See the FUNCTIONAL CHANGES section below for
* more information.
* \i PING_OPT_NOHOST
* Suppress host lookup. This is useful when you have the DNS resolver
* but the DNS server is down and not returning host names. When ping()
* receives a response it tries to convert the IP address of the peer to
* its hostname so that it can be displayed. If the entry is not available
* in the local host table, then the DNS server will be contacted. If the
* server does not respond the first time, the resolver makes multiple
* attempts to contact the server and then times out if no response is
* received. By default it makes a maximum of 2 attempts with a starting
* timeout of 5 seconds which results in a total timeout period of 15 seconds.
* If the number of attempts is increased to 4, this timeout can extend
* upto 75 seconds (because of exponential backoff between retries). During
* this time it may appear that the ping call has stalled and it will not
* return. In that case wait a few minutes to see if the call returns.
* Sometimes the DNS server information specified to the resolver is
* incorrect, especially if the default settings were not changed at all
* when the DNS resolver component was included. Check the settings and
* confirm whether the server is reachable or not.
*
* The PING_OPT_NOHOST option flag is functionally equivalent to the '-n'
* command option. See the FUNCTIONAL CHANGES section below for more
* information.
* \ie
*
* The following global variables are also maintained for backward compatibility
* and can be set from the target shell or Windsh to configure the ping()
* parameters:
* \is
* \i '_pingTxLen'
* Size of the ICMP echo packet (default 64, min 8, max 65516). This is
* functionally equivalent to the '-s \<packetsize\>' option. See the FUNCTIONAL
* CHANGES section below for more information.
* \i '_pingTxTmo'
* Packet timeout in seconds (default 1 second). This is functionally
* equivalent to the '-w \<timeout\>' option. See the FUNCTIONAL CHANGES
* section below for more information.
* \ie
*
* NOTE:
* If you have included the DNS resolver, not specified the PING_OPT_NOHOST
* option and you notice that ping() is taking a long time (more than the
* timeout, _pingTxTmo) to return, check your resolver settings to see if
* the server has been specified correctly. It is also possible that
* the server is specified correctly but it is down. See the description
* for the PING_OPT_NOHOST option if you see this problem.
*
* FUNCTIONAL CHANGES:
*
* The following describes the behavior changes of the ping() functionalities
* that are available in previous release of the Wind River network stack.
*
* PACKET TIMEOUT:
*
* The default packet timeout has been changed from 5 seconds to 1 second.
* This is done to accommondate the default value implemented by the IPNet
* stack. The packet timeout value can be changed either by setting the
* _pingTxTmo global variable or specifying the '-w \<timeout\>' option. See
* the NEW OPTIONS section below for more information.
*
* NUMBER OF PACKETS RECEIVED:
*
* Previously, 'ping' runs continuously if the number of ICMP packets to receive
* from the remote host is not specified using the \<numPackets\> argument.
* This is now changed such that ping will stop after 4 echoed packets are
* received. To run 'ping' continuously, use the '-c' option with a \<count\>
* argument of -1. See the NEW OPTIONS section below for more information.
*
* NEW OPTIONS:
*
* The following are the new \<options\> that have been added:
* \ts
* Option | Description
* ------------------+----------------------------------------------------------
* 'A' | Add router alert option to each sent ping request.
* '-b' | Allow pinging a broadcast address.
* '-c' <count> | Stop after sending count ECHO_RESPONSE packets. If this
* | option is specified, the \<numPackets\> argument will
* | be ignored.
* '-D' | Set the DF (don't fragment) flag on each sent ping
* | request.
* '-I' <ifname> | Specify outgoing interface.
* '-n' | Numeric output only. No attempts will be made to look up
* | names for host addresses.
* '-r' | Bypass the normal routing tables and send directly to a
* | host on an attached network. This option is functionally
* | equivalent to setting the \<flags\> arguemnt to
* | PING_OPT_DONTROUTE.
* '-s' <packetsize> | Specifies the number of data bytes to be sent. The
* | default is 56, which translates into 64 ICMP data bytes
* | when combined with the 8 bytes of ICMP header data.
* '-S' <src_addr> | Specifies the address to use a source address when
* | sending.
* '-t' <ttl> | Use the specified time-to-live.
* '-T' <options> | Include IP timestamp option. timestamp can be tsonly
* | (only timestamp), tsandaddr (address and timestamp) or
* | tsprespec host1 [host2 [host3 [host4]]]
* | (timestamp specific hops)
* '-x' | Send a ICMP timestamp request instead of a ECHO request.
* '-V' <vr> | Specify virtual router. 0 if not specified.
* '-w' <timeout> | Timeout in milliseconds, default is 1000 ms. This option
* | is functionally equivalent to setting the _pingTxTmo
* | global variable.
* ------------------+----------------------------------------------------------
* \te
*
* UNSUPPORTED OPTION FLAGS:
*
* The following optional flags which may be given through the \<flags\>
* parameter are no longer supported:
* \is
* \i PING_OPT_DEBUG
* Enables debug output.
* \ie
*
* UNSUPPORTED GLOBALS:
*
* The following global variables which previously can be set from the target
* shell or Windsh to configure the ping() parameters are no longer supported:
* \is
* \i '_pingSockBufSize'
* Size of the socket buffer (default 8192). The socket buffer size is now
* determined and set to the appropriate value internally by ipnet_cmd_ping()
* based on the <packetsize> specified by the '-s' option.
* \i '_pingTxInterval'
* Packet interval in seconds (default 1 second).
* \ie
*
* RTP SUPPORT:
*
* Running ping as an RTP executable from the 'cmd' shell is currently not
* supported.
*
* RETURNS:
* OK, or ERROR if the remote host is not reachable.
*
* ERRNO: N/A
*
*/
STATUS ping
(
char *host, /* parameters plus host address */
int numPackets, /* number of packets to receive */
ulong_t options /* option flags */
)
{
char args[32]; /* enough for adding "-c4000111222" and other "options" */
size_t len;
int pingLen;
int msecTimeout;
int ret = ERROR;
PING_SESSION * pSession = NULL;
char * newString;
char * p;
char * pEnd;
TASK_ID tid;
if (host == NULL) /* let ipnet_cmd_ping_stoppable() print the usage */
{
char * argv[2];
argv[0] = "ping";
argv[1] = IP_NULL;
(void)ipnet_cmd_ping_stoppable(1, argv, NULL);
return ERROR;
}
if (numPackets < 0)
{
printf("ping: Invalid arguments\n");
errnoSet(EINVAL);
return ERROR;
}
/* check for unsupported option flags */
if (options & PING_OPT_DEBUG)
{
printf("Unsupported PING_OPT_DEBUG(0x%x) option flag\n",
PING_OPT_DEBUG);
errnoSet(EINVAL);
return ERROR;
}
if (ipcom_once(&ping_init_once, ping_lib_init, IP_NULL) != IPCOM_SUCCESS)
{
return ERROR;
}
/*
* calculate size needed for session data
* including argv array and underlying strings
*/
len = sizeof (PING_SESSION) + strlen(host);
len += 5 /* "ping " */
+ 8 /* "-silent " -- PING_OPT_SILENT */
+ 13 /* "-c2147483647 " -- packet count option */
+ 8 /* "-s65536 " -- packet length option */
+ 13 /* "-w2147483647 " -- ping timeout in ms */
+ 3 /* "-r " -- PING_OPT_DONTROUTE */
+ 3 /* "-n " -- PING_OPT_NOHOST */
+ 16; /* trailing NUL plus slop */
(void) taskSafe();
pSession = calloc(1, len);
if (pSession == NULL)
goto unsafe;
p = (char *)(pSession + 1);
pEnd = ((char *)pSession) + len;
p = strendcpy(p, pEnd, "ping");
++p; /* bypass terminating NUL for command name "ping" */
newString = p; /* start of arguments */
if (options & PING_OPT_SILENT)
{
p = strendcpy(p, pEnd, "-silent ");
}
if (numPackets != 0)
{
(void) sprintf(args, "-c%d ", numPackets);
p = strendcpy (p, pEnd, args);
}
/* check the size of the ICMP echo packet */
pingLen = _pingTxLen;
if (pingLen != 64) /* default size of icmp echo packet */
{
if (pingLen > PING_MAXPACKET - 20)
{
if (!(options & PING_OPT_SILENT))
printf("datalen value too large, reducing to %d\n",
PING_MAXPACKET-20);
_pingTxLen = pingLen = PING_MAXPACKET - 20;
}
else if (pingLen < 8) /* for backward compatibility */
{
if (!(options & PING_OPT_SILENT))
printf("datalen value too small, setting to 8\n");
_pingTxLen = pingLen = 8;
}
(void) sprintf(args, "-s%d ", pingLen);
p = strendcpy(p, pEnd, args);
}
/* check the packet timeout value */
msecTimeout = _pingTxTmo * 1000; /* IPNet ping timeout is in msec */
if (msecTimeout != 1000) /* default IPNet ping timeout is 1000 ms */
{
(void) sprintf(args, "-w%d ", msecTimeout);
p = strendcpy (p, pEnd, args);
}
if (options & PING_OPT_DONTROUTE) /* disallow packet routing ? */
p = strendcpy(p, pEnd, "-r ");
if (options & PING_OPT_NOHOST) /* lookup hosts or not? */
p = strendcpy(p, pEnd, "-n ");
p = strendcpy(p, pEnd, host);
/* just in case, check for truncation */
if (p == pEnd)
{
if (!(options & PING_OPT_SILENT))
printf("ping: allocated argument string too short!\n");
errnoSet (EINVAL);
goto give_up;
}
ret = getOptServ(newString,
(char *)(pSession + 1), /* "ping" is here */
&pSession->argc,
pSession->argv,
PING_MAXARGS + 2);
if (ret != OK)
{
printf("ping: invalid arguments\n");
errnoSet(EINVAL);
goto give_up;
}
pSession->shellTcb = taskTcb(0);
pSession->shellTaskDone = IP_FALSE; /* redundant */
pSession->pingTaskDone = IP_FALSE; /* redundant */
ret = ERROR;
if (semTake (ping_sessions_mutex, WAIT_FOREVER) != OK)
{
goto give_up;
}
if (ipcom_list_length (&ping_sessions) == 0)
{
if (taskDeleteHookAdd((FUNCPTR)ping_delete_hook) != OK)
{
(void) semGive (ping_sessions_mutex);
printErr("Error installing deletion hook!\n");
goto give_up;
}
}
/*
* Note, before this, pSession->stop is
* IPNET_PING_CMD_NO_PING_IN_PROGRESS, but it doesn't matter.
*/
pSession->stop = IPNET_PING_CMD_PINGING;
ipcom_list_insert_first (&ping_sessions, &pSession->entry);
(void) semGive (ping_sessions_mutex);
/* the current task is still deletion safe */
tid = taskSpawn("tPingTask",
ipcom_priority_map[IPCOM_PRIORITY_DEFAULT],
0,
IPCOM_PROC_STACK_DEFAULT,
(FUNCPTR)pingtask,
(_Vx_usr_arg_t)pSession,
0, 0, 0, 0, 0, 0, 0, 0, 0);
if (tid == TASK_ID_ERROR)
{
pSession->pingTaskDone = IP_TRUE;
/* ret is still ERROR */
}
else
{
/*
* Spawned pingtask() successfully.
* Now unlock deletion safety, so that if we were called from
* the shell, the ping() command can be terminated (and the
* shell restarted, ugh) using Ctrl-C. If this happens,
* the delete hook will be run.
*/
(void) taskUnsafe();
while (*(volatile int *)&pSession->stop !=
IPNET_PING_CMD_NO_PING_IN_PROGRESS)
{
ipcom_millisleep(100);
}
VX_MEM_BARRIER_R();
(void) taskSafe();
ret = pSession->pingRet;
if (ret != 0)
errnoSet (pSession->pingErr);
}
ping_session_release(pSession, PING_SESSION_SHELL_TASK);
/* do not touch pSession any more */
unsafe:
(void) taskUnsafe();
return ret;
give_up:
free (pSession);
goto unsafe;
}
@@ -0,0 +1,395 @@
/* routeCmd.c - utility to manually manipulate the network routing table */
/*
* Copyright (c) 2006 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.
*/
/*
modification history
--------------------
01d,15sep10,xhs support IPLITE
01c,22aug06,kch Fixed warning and minor doc update.
01b,03aug06,kch Modified routec() to allow invocation with no argument.
01a,27jul06,kch Written.
*/
/*
DESCRIPTION
This library provides a backward-compatible interface for routec() available
in the previous releases of the Wind River network stack. The routine is
now a wrapper implemented in terms of the preferred routine ipnet_cmd_route()
which is available in the IPNet stack.
INCLUDE FILES: net/utils/routeCmd.h
*/
#define IPCOM_SKIP_NATIVE_SOCK_API
#include <ipcom_vxworks.h>
#include <ipcom_err.h>
#include <ipnet.h>
#include <errnoLib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <net/utils/routeCmd.h>
#define ROUTEC_MAXARGS 50
/*******************************************************************************
*
* routec - manipulate the contents of the routing table
*
* Use routec() to manually add, delete, or modify entries in the routing
* table. For the most part, this work is handled by a routing protocol, but
* this function is useful at boot time or when testing networked applications.
* The API for routec() is oriented towards command-line use, but it can be
* used programmatically. The valid 'routec' command-line syntax is as follows:
* \ss
* 'routec' "[<options>] <command> [ [<modifiers>] <arguments> ]"
* \se
* Which has three main variants:
* \ss
* 'routec' "['-n'] <command> ['-net|-host'] <IPv4dest> <gateway> [<netmask>]"
* 'routec' "['-n'] <command> ['-net|-host'] <IPv6dest> <gateway> [<prefixlen>]"
* \se
* The first variant deletes routes from the route table. If you leave <family>
* unspecified, a 'routec "flush"' call removes all routes from the route table.
* If <family> is specified, only routes having destinations with addresses in
* the specified <family> are deleted. Valid values for <family> are 'inet', for
* routes with IPv4 destination addresses, and 'inet6', for routes with IPv6
* destination addresses.
*
* OPTIONS
*
* Use the <options> of a routec() call as follows:
* \ts
* Option | Description
* --------+------------------------------------------------------------------
* '-n' | No name translation for numerical addresses.
* \te
* Turning off name translation is often a good idea when debugging network
* problems. This is because the process of translating to symbolic names
* from numerical equivalents typically requires a correctly functioning
* network. In addition, even if the network is functioning normally, name
* translation can sometimes take more time than you want to wait.
*
* COMMANDS
*
* Use the <command> element of a routec() call as follows:
* \ts
* Command | Description
* ---------+------------------------------------------------------------------
* 'add' | Add a route.
* 'delete' | Delete a specific route.
* 'change' | Change the contents (gateways, etc.) of a route.
* 'get' | Lookup and display the route for a destination.
* 'monitor'| Continuously report any changes to the routing information base,
* | routing lookup misses, or suspected network partitionings.
* | The monitor command has the syntax:
* | routec [-n] monitor
* \te
*
* MODIFIERS
*
* Use the routec() command modifiers as follows:
* \ts
* Modifier | Description
* -------------|-------------------------------------------------------------
* '-net' | Command applies to a network route.
* '-host' | Command applies to a host route.
* _____________|_____________________________________________________________
* '-netmask' | For specifying subnet masks.
* '-prefixlen' | For specifying an IPv6 prefix length.
* _____________|_____________________________________________________________
* '-netmask' | For specifying subnet masks.
* '-cloning' | RTF_CLONING, generates a new route on use.
* '-xresolve' | RTF_XRESOLVE, emit message on use (for external lookup).
* '-iface' | ~RTF_GATEWAY, destination is directly reachable.
* '-static' | RTF_STATIC, manually added route.
* '-nostatic' | ~RTF_STATIC, pretend the route was added by kernel or daemon.
* '-reject' | RTF_REJECT, emit an ICMP unreachable when matched.
* '-blackhole' | RTF_BLACKHOLE, silently discard packets (during updates).
* '-proto1' | RTF_PROTO1, set protocol-specific routing flag #1.
* '-proto2' | RTF_PROTO2, set protocol-specific routing flag #2.
* '-llinfo' | RTF_LLINFO, translates a protocol address to a link address.
* _____________|_____________________________________________________________
* '-rtt' | Metric for transport level protocol.
* '-rttvar' | Metric for transport level protocol.
* '-mtu' | Metric for transport level protocol.
* '-hopcount' | Metric for transport level protocol.
* '-expire' | Metric for transport level protocol.
* _____________|_____________________________________________________________
* \te
* Use the '-net' or '-host' modifiers to force routec() to interpret the
* command as applying to a network route or a host route. Otherwise, the
* command could make assumptions based on the <destination> value.
*
* Use the '-netmask' modifier to achieve the effect of an OSI ESIS redirect
* or to manually add subnet routes with netmasks different from that of the
* implied network interface (as would otherwise be communicated using the
* OSPF or ISIS routing protocols). You specify an additional ensuing address
* parameter (to be interpreted as a network mask). The implicit network mask
* generated in the IPv4 case can be overridden by making sure this option
* follows the <destination> value.
*
* Use the third group of modifiers shown above to clear or set one of the
* 'RTF_*' flags associated with a route. These flags influence the behavior
* protocols when sending to destinations matched by the routes.
*
* Use the optional '-proxy' modifier to specify that the RTF_LLINFO routing
* table entry is the "published (proxy-only)" ARP entry.
*
* You can use last group of optional modifiers shown above ('-rtt', '-rttvar',
* '-sendpipe' and the rest) to provide initial values to quantities maintained
* in the routing entry by transport level protocols, such as TCP or TP4. You
* can individually lock these metrics by preceding each modifier to be locked
* by the '-lock' meta-modifier. Alternatively, you can specify that all
* ensuing metrics be locked by specifying the '-lockrest' meta-modifier.
*
* DESTINATION ADDRESSES
*
* All the commands above expect a <destination> value. You can specify the
* <destination> using a symbolic name or using an Internet address. If the
* family is 'inet', a destination of 'default' is a synonym for '-net
* 0.0.0.0', which is the default route.
*
* The format you use to specify an Internet <destination> address varies
* according to whether you want to specify an IPv4 or IPv6 address. In
* addition, routec() allows you to use contracted address forms that are
* more convenient to type on a command line. However, you need to remember
* that these contracted forms often imply a '-net' or '-host' modifier that
* you will need to override explicitly if it is inappropriate. For example:
* \ts
* Destination | Interpretation
* ----------------+-------------------------------------------
* 128.32 | -host 128.0.0.32
* 128.32.130 | -host 128.32.0.130
* -net 128.32 | 128.32.0.0
* -net 128.32.130 | 128.32.130.0
* 192.168.64/20 | -net 192.168.64 -netmask 255.255.240.0
* \te
*
* If the destination has a "local address part" of INADDR_ANY (0.0.0.0), or
* if the destination is the symbolic name of a network, then the route is
* assumed to be to a network. Otherwise, it is presumed to be a route to a
* host. Optionally, the destination could also be specified in the net/bits
* format.
*
* For IPv6 addresses, use the '-prefixlen' qualifier instead of the '-netmask'
* qualifier because non-continuous masks are not allowed in IPv6. For example,
* "'-prefixlen 32'" specifies network mask of:
*
* 'ffff:ffff:0000:0000:0000:0000:0000:0000'
*
* The default value of '-prefixlen' is 64 for compatibility with the IPv6
* aggregatable address conventions, but 0 is assumed if you specify
* 'default'. Note that the '-prefixlen' qualifier applies only for the IPv6
* address family.
*
* When using IPv6 addresses, specify the flag '-inet6'.
* Remember to include the scope for link-local addresses, for example:
*
* \cs
* routec "get -inet6 fe80::a00:3eff:fe33:201%fei0"
* \ce
*
* GATEWAY ADDRESSES
*
* The <gateway> value indicates the next-hop intermediary through which packets
* should be routed. All symbolic names specified for a <destination> or
* <gateway> value are looked up first as a host name. If this lookup fails,
* the routec() call interprets the name as that of a network.
*
* DIAGNOSTICS
*
* In the messages output from a routec() call, you may see the following
* diagnostic messages.
* \ss
* add [host | network ] %s: gateway %s flags %x
* \se
* The specified route is being added to the tables. If the gateway address
* used was not the primary address of the gateway, the gateway address is
* printed numerically as well as symbolically.
* \ss
* delete [ host | network ] %s: gateway %s flags %x
* \se
* As above, but when deleting an entry.
* \ss
* Network is unreachable
* \se
* An attempt to add a route failed because the gateway listed was not on
* a directly connected network. You must provide the next-hop gateway.
* \ss
* not in table
* \se
* A delete was attempted for an entry that was not present in the tables.
* \ss
* routing table overflow
* \se
* An add was attempted, but the system was low on resources and was unable
* to allocate the memory needed to create the new entry.
* \ss
* gateway uses the same route
* \se
* A change operation resulted in a route whose gateway uses the same route
* as the one being changed. The next-hop gateway should be reachable
* through a different route.
*
* NEW FUNCTIONALITIES
*
* The following are the new functionalities that have been added:
*
* NEW OPTIONS:
* \ts
* Option | Description
* ---------------+-------------------------------------------------------------
* '-nollinfo' | Do not show routes which have the LLINFO flag set.
* '-V <vr>' | Specify virtual router index. 0 if not specified.
* '-T <table>' | Specify route table ID. 0 if not specified.
* '-dev <ifname> | Device name.
* \te
*
* NEW COMMANDS:
* \ts
* Command | Description
* --------+----0---------------------------------------------------------------
* 'vr' | Add/delete a virtual route table.
* 'show' | Print out the route table similar to netstat -r
* \te
*
* The vr command has the syntax:
* routec [-add | -delete] vr_index
* vr_index 0 (the default route table) cannot be added or deleted. The new
* route table will be completely empty.
*
* NEW MODIFIERS
* \ts
* Modifier | Description
* -------------|-------------------------------------------------------------
* '-pref ' | IPNET_RTF_PREF, always prefer this route.
* '-value5' | IPNET_RTF_SRCADDR, gateway specifies the default source
* | address.
* \te
*
* FUNCTIONAL CHANGES:
*
* The following describes the behavior changes of the routec() functionalities
* that are available in previous release of the Wind River network stack.
*
* UNSUPPORTED OPTIONS:
*
* The following <options> are no longer supported:
* \ts
* Option | Description
* --------+------------------------------------------------------------------
* '-d' | Dry run, no changes to the route table but simulates the messages.
* '-v' | Verbose, print additional details.
* '-q' | Quiet, suppress all output.
* \te
*
* UNSUPPORTED COMMANDS:
*
* The following command modifiers are no longer supported:
* \ts
* Command | Description
* -----------+----------------------------------------------------------------
* 'flush' | Flush routes out of the routing table.
* 'newget' | Lookup and display the route for a destination using gateway
* | and protocol as additional search parameters.
* 'newchange'| Change the contents (gateways, etc.) of a route. Allows the
* | specification of the route gateway and protocol to identify the
* | the route to be modified
* 'getall' | Retrieve a list of routes to the same destination
* \te
*
* UNSUPPORTED MODIFIERS
* \ts
* Modifier | Description
* -------------|-------------------------------------------------------------
* '-interface' | Command applies to an interface route.
* _____________|_____________________________________________________________
* '-proxy' | RTF_LLINFO entry is the "published (proxy-only)" ARP entry.
* _____________|_____________________________________________________________
* '-sendpipe' | Metric for transport level protocol.
* '-recvpipe' | Metric for transport level protocol.
* '-ssthresh' | Metric for transport level protocol.
* '-value1' | Metric for transport level protocol.
* '-value2' | Metric for transport level protocol.
* '-value3' | Metric for transport level protocol.
* '-value4' | Metric for transport level protocol.
* '-value5' | Metric for transport level protocol.
* '-routetag' | Metric for transport level protocol.
* _____________|_____________________________________________________________
* '-proto' | For specifying route protocol
* '-tos' | For specifying route tos
* '-weight' | For specifying route weight
* '-oldgate' | For specifying old gateway (used with newchange)
* _____________|_____________________________________________________________
* \te
*
* RETURNS: 0 on success, or a value other than zero if an error occurs
*
* ERRNO: N/A
*
*/
int routec
(
char * paramString /* a string of command options. */
)
{
int argc;
char *tempArgv [ROUTEC_MAXARGS + 2];
char *newString = NULL;
char **argv = tempArgv;
int ret = OK;
size_t alen=0;
if (paramString == NULL) /* let ipnet_cmd_route() prints the usage */
{
argv[0] = "route";
argc = 1;
goto cmd;
}
alen = strlen (paramString) + 1;
if ((newString = calloc (1, alen))==NULL)
{
printf("routec: calloc failed\n");
return ERROR;
}
strcpy (newString,paramString);
ret = getOptServ (newString, "route", &argc, argv, ROUTEC_MAXARGS + 2);
if (ret != OK)
{
printf ("Too many arguments.\n");
errnoSet(EINVAL);
goto done;
}
cmd:
#if _WRS_CONFIG_COMPONENT_IPLITE
if ((ret = iplite_cmd_route (argc, argv)) == IPCOM_SUCCESS)
#else
if ((ret = ipnet_cmd_route (argc, argv)) == IPCOM_SUCCESS)
#endif
{
ret = OK;
goto done;
}
/* Convert the IPCOM error code to VxWorks errno */
errnoSet(IPCOM_ERRNO(ret));
ret = ERROR;
done:
if (newString)
free (newString);
return (argc == 1) ? 0 : ret; /* override ret if usage is printed */
}