316 lines
9.6 KiB
C
316 lines
9.6 KiB
C
/* m2Ipv6UdpLib.c - MIB-II IPv6 UDP-group API for SNMP agents */
|
|
|
|
/* Copyright 1984 - 2003 Wind River Systems, Inc. */
|
|
#include "copyright_wrs.h"
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01d,12jan05,vvv osdep.h cleanup
|
|
01c,06nov03,rlm Ran batch header update for header re-org.
|
|
01b,08sep03,vvv merged from ACCORDION_BASE6_MERGE_BASELINE
|
|
01a,20mar02,ant taken from m2UdpLib.c
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This library provides MIB-II services for the UDP group for IPv6. It provides
|
|
routines to initialize the group, and read the table of IPv6 UDP listeners. For
|
|
a broader description of IPv6 MIB-II services, see the manual entry for m2Ipv6Lib.
|
|
|
|
To use this feature, include the following component:
|
|
INCLUDE_MIB2_UDPV6
|
|
|
|
USING THIS LIBRARY
|
|
This library can be initialized and deleted by calling m2Ipv6UdpInit() and
|
|
m2Ipv6UdpDelete() respectively, if only the IPv6 UDP group's services are
|
|
needed. If full IPv6 MIB-II support is used, this group and all other IPv6
|
|
groups can be initialized and deleted by calling m2Ipv6Init() and m2Ipv6Delete().
|
|
|
|
The IPv6 UDP table of listeners can be accessed in lexicographical order.
|
|
The first entry in the table can be accessed by setting the table index to zero
|
|
in a call to m2Ipv6UdpTblEntryGet(). Every other entry thereafter can be
|
|
accessed by repeatedly calling m2Ipv6UdpTblEntryGet() with the M2_NEXT_VALUE
|
|
constant as the search parameter. For example:
|
|
.CS
|
|
M2_IPV6UDPTBL udpEntry;
|
|
|
|
/@ Specify zero index to get the first entry in the table @/
|
|
|
|
/@ local IPv6 Address in host byte order @/
|
|
memset (udpEntry.ipv6udpLocalAddress, 0, sizeof (struct in6_addr));
|
|
udpEntry.ipv6udpLocalPort = 0; /@ local port number in host byte order @/
|
|
|
|
/@ get the first entry in the table @/
|
|
|
|
if ((m2Ipv6UdpTblEntryGet (M2_NEXT_VALUE, &udpEntry) == OK)
|
|
/@ values in udpEntry in the first entry are valid @/
|
|
|
|
/@ process first entry in the table @/
|
|
|
|
/@ get the second entry in the table @/
|
|
|
|
if ((m2Ipv6UdpTblEntryGet (M2_NEXT_VALUE, &udpEntry) == OK)
|
|
/@ values in udpEntry in the second entry are valid @/
|
|
.CE
|
|
|
|
INCLUDE FILES: m2Ipv6Lib.h
|
|
|
|
SEE ALSO:
|
|
m2Ipv6Lib, m2Ipv6IfLib, m2Ipv6IfIcmpLib, m2Ipv6TcpLib, m2Ipv6MldLib
|
|
*/
|
|
|
|
/* includes */
|
|
|
|
#include <vxWorks.h>
|
|
|
|
#include <netconf.h>
|
|
#include <vwModNum.h>
|
|
#include <m2Lib.h>
|
|
#include <sys/socket.h>
|
|
#include <net/route.h>
|
|
#include <netinet/in_systm.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/ip.h>
|
|
#include <netinet/ip_var.h>
|
|
#include <netinet/udp.h>
|
|
#include <netinet/udp_var.h>
|
|
#include <netinet/in_pcb.h>
|
|
#include "errnoLib.h"
|
|
#include <m2Ipv6Lib.h>
|
|
|
|
#ifdef VIRTUAL_STACK
|
|
#include <netinet/vsLib.h>
|
|
#include <netinet/vsUdp.h>
|
|
#include <netinet/vsData.h>
|
|
#endif /* VIRTUAL_STACK */
|
|
|
|
/* external declarations */
|
|
|
|
#ifndef VIRTUAL_STACK
|
|
extern struct udpstat udpstat; /* UDP statistics variable */
|
|
extern struct inpcbhead udb; /* UDP link list of listen requests */
|
|
#endif /* VIRTUAL_STACK */
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* m2Ipv6UdpInit - initialize MIB-II IPv6 UDP-group access
|
|
*
|
|
* This routine allocates the resources needed to allow access to the IPv6 UDP
|
|
* MIB-II variables. This routine must be called before any IPv6 UDP variables
|
|
* can be accessed.
|
|
*
|
|
* RETURNS: OK, always.
|
|
*
|
|
* SEE ALSO: m2Ipv6UdpTblEntryGet(), m2Ipv6UdpDelete()
|
|
*/
|
|
|
|
STATUS m2Ipv6UdpInit (void)
|
|
{
|
|
return (OK);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2Ipv6AddrCmp - compare two ipv6 addresses
|
|
*/
|
|
|
|
LOCAL int m2Ipv6AddrCmp
|
|
(
|
|
struct in6_addr * pAddr1,
|
|
struct in6_addr * pAddr2
|
|
)
|
|
{
|
|
int ix;
|
|
|
|
for (ix = 0; ix < 4; ix++)
|
|
{
|
|
if (pAddr1->s6_addr32[ix] > pAddr2->s6_addr32[ix])
|
|
return (1);
|
|
else if (pAddr1->s6_addr32[ix] < pAddr2->s6_addr32[ix])
|
|
return (-1);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* m2Ipv6UdpCmp - compare two entry indexes of the IPv6 UDP listeners table
|
|
*
|
|
* RETURNS: 0 = equal, 1 > greater than, and -1 < less than.
|
|
*
|
|
* SEE ALSO: N/A
|
|
*/
|
|
|
|
LOCAL int m2Ipv6UdpCmp
|
|
(
|
|
M2_IPV6UDPTBL * pVal1, /* pointer to UDP table entry (Compare againts) */
|
|
M2_IPV6UDPTBL * pVal2 /* pointer to UDP table entry (Second entry) */
|
|
)
|
|
{
|
|
int result;
|
|
|
|
/* Comparison of two IPv6 addresses */
|
|
|
|
result = m2Ipv6AddrCmp((struct in6_addr *)pVal1->ipv6UdpLocalAddress,
|
|
(struct in6_addr *)pVal2->ipv6UdpLocalAddress);
|
|
|
|
if (result > 0)
|
|
{
|
|
return 1; /* First Entry is Greater */
|
|
}
|
|
|
|
if (result < 0)
|
|
{
|
|
return -1; /* First Entry is Smaller */
|
|
}
|
|
|
|
/* Comparison of two signed values */
|
|
|
|
result = pVal1->ipv6UdpLocalPort - pVal2->ipv6UdpLocalPort;
|
|
|
|
if (result != 0)
|
|
return (result); /* Value > 0 or < 0 */
|
|
|
|
/* Result will determine Equal, Less than or Greater than */
|
|
|
|
return (pVal1->ipv6UdpIfIndex - pVal2->ipv6UdpIfIndex);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* m2Ipv6UdpTblEntryGet - get a MIB-II IPv6 UDP listener table entry
|
|
*
|
|
* This routine traverses the IPv6 UDP table and does an M2_EXACT_VALUE or
|
|
* a M2_NEXT_VALUE search based on the <search> parameter. The calling routine
|
|
* is responsible for supplying a valid MIB-II entry index in the input structure
|
|
* <pUdpEntry>. The index is made up of the IPv6 address, the local port number,
|
|
* and the 'ipv6UdpIfIndex'. The first entry in the table is retrieved by doing
|
|
* a M2_NEXT_VALUE search with the index fields set to zero.
|
|
*
|
|
* RETURNS:
|
|
* OK, or ERROR if the input parameter is not specified or a match is not found.
|
|
*
|
|
* ERRNO:
|
|
* S_m2Lib_INVALID_PARAMETER
|
|
* S_m2Lib_ENTRY_NOT_FOUND
|
|
*
|
|
* SEE ALSO: m2Ipv6UdpInit(), m2Ipv6UdpDelete(), m2Ipv6UdpLib
|
|
*/
|
|
|
|
STATUS m2Ipv6UdpTblEntryGet
|
|
(
|
|
int search, /* M2_EXACT_VALUE or M2_NEXT_VALUE */
|
|
M2_IPV6UDPTBL * pUdpEntry /* ptr to the requested entry */
|
|
)
|
|
{
|
|
M2_IPV6UDPTBL savedEntry; /* Possible M2_NEXT_VALUE Entry in UDP */
|
|
/* table */
|
|
M2_IPV6UDPTBL currEntry;
|
|
int netLock; /* Use to secure the Network Code Access */
|
|
struct inpcb * pPcb; /* Pointer to UDP Listener structure. */
|
|
|
|
/* Validate Pointer to UDP Table Entry structure */
|
|
|
|
if (pUdpEntry == NULL)
|
|
{
|
|
errnoSet (S_m2Lib_INVALID_PARAMETER);
|
|
return (ERROR);
|
|
}
|
|
|
|
/*
|
|
* Initialize Entry for M2_NEXT_VALUE entry search. Not used in
|
|
* M2_EXACT_VALUE search.
|
|
*/
|
|
|
|
/* Largest possible value. */
|
|
memset (savedEntry.ipv6UdpLocalAddress, 0xff, sizeof (struct in6_addr));
|
|
savedEntry.ipv6UdpLocalPort = -1; /* Largest possible value. */
|
|
savedEntry.ipv6UdpIfIndex = -1; /* Largest ifIndex */
|
|
|
|
netLock = splnet (); /* Get exclusive access to Network Code */
|
|
|
|
for (pPcb = udb.lh_first; pPcb != NULL; pPcb = pPcb->inp_list.le_next )
|
|
{
|
|
if ((pPcb->inp_vflag & INP_IPV6) == 0) /* check only ipv6 blocks */
|
|
continue;
|
|
|
|
memcpy (currEntry.ipv6UdpLocalAddress, &pPcb->in6p_laddr, sizeof (struct in6_addr));
|
|
NTOHL_IPV6ADDR(currEntry.ipv6UdpLocalAddress);
|
|
|
|
currEntry.ipv6UdpLocalPort = ntohs (pPcb->inp_lport);
|
|
|
|
currEntry.ipv6UdpIfIndex = pPcb->inp6_ifindex;
|
|
|
|
if (search == M2_EXACT_VALUE)
|
|
{
|
|
/* Check that the specified index matches the current entry */
|
|
|
|
if (m2Ipv6UdpCmp(&currEntry, pUdpEntry) == 0)
|
|
{
|
|
splx (netLock); /* Give up exclusive access to Network Code */
|
|
return (OK); /* The answer is in the structure pUdpEntry */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* A NEXT search is satisfied by an entry that is lexicographicaly
|
|
* equal to or greater than the input UDP connection entry. Because
|
|
* the UDP connection list is not in order, the list must be
|
|
* traverse completely before a selection is made. The rules for a
|
|
* lexicographical comparison are built in the next statement.
|
|
*/
|
|
|
|
if ((m2Ipv6UdpCmp(&currEntry, pUdpEntry) > 0) &&
|
|
(m2Ipv6UdpCmp(&currEntry, &savedEntry) < 0))
|
|
{
|
|
/*
|
|
* Save the entry which qualifies as the NEXT greater
|
|
* lexicographic entry. Because the table is not order the
|
|
* search must proceed to the end of the table.
|
|
*/
|
|
|
|
memcpy (savedEntry.ipv6UdpLocalAddress, currEntry.ipv6UdpLocalAddress,
|
|
sizeof (struct in6_addr));
|
|
savedEntry.ipv6UdpIfIndex = currEntry.ipv6UdpIfIndex;
|
|
savedEntry.ipv6UdpLocalPort = currEntry.ipv6UdpLocalPort;
|
|
}
|
|
}
|
|
}
|
|
|
|
splx (netLock); /* Give up exclusive access to Network Code */
|
|
|
|
/* If a match was found fill, the requested structure */
|
|
|
|
if (savedEntry.ipv6UdpLocalPort != -1)
|
|
{
|
|
memcpy (pUdpEntry->ipv6UdpLocalAddress, savedEntry.ipv6UdpLocalAddress,
|
|
sizeof (struct in6_addr));
|
|
pUdpEntry->ipv6UdpLocalPort = savedEntry.ipv6UdpLocalPort;
|
|
pUdpEntry->ipv6UdpIfIndex = savedEntry.ipv6UdpIfIndex;
|
|
return (OK);
|
|
}
|
|
|
|
errnoSet (S_m2Lib_ENTRY_NOT_FOUND);
|
|
return (ERROR);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* m2Ipv6UdpDelete - delete all resources used to access the IPv6 UDP group
|
|
*
|
|
* This routine frees all the resources allocated at the time the group was
|
|
* initialized. The IPv6 UDP group should not be accessed after this routine has
|
|
* been called.
|
|
*
|
|
* RETURNS: OK, always.
|
|
*
|
|
* SEE ALSO: m2Ipv6UdpInit(), m2Ipv6UdpTblEntryGet(), m2Ipv6UdpLib
|
|
*/
|
|
|
|
STATUS m2Ipv6UdpDelete (void)
|
|
{
|
|
return (OK);
|
|
}
|