original files of m241
This commit is contained in:
@@ -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 */
|
||||
}
|
||||
Reference in New Issue
Block a user