freebsd-dev/sbin/atm/atm/atm_show.c
Colin Percival 1b49e5051e style cleanup: Remove duplicate $FreeBSD$ tags.
These files had tags after the copyright notice,
inside the comment block (incorrect, removed),
and outside the comment block (correct).

Approved by:	rwatson (mentor)
2004-02-10 20:48:08 +00:00

1145 lines
23 KiB
C

/*
*
* ===================================
* HARP | Host ATM Research Platform
* ===================================
*
*
* This Host ATM Research Platform ("HARP") file (the "Software") is
* made available by Network Computing Services, Inc. ("NetworkCS")
* "AS IS". NetworkCS does not provide maintenance, improvements or
* support of any kind.
*
* NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
* SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
* In no event shall NetworkCS be responsible for any damages, including
* but not limited to consequential damages, arising from or relating to
* any use of the Software or related support.
*
* Copyright 1994-1998 Network Computing Services, Inc.
*
* Copies of this Software may be made, however, the above copyright
* notice must be reproduced on all copies.
*/
/*
* User configuration and display program
* --------------------------------------
*
* Routines for "show" subcommand
*
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netatm/port.h>
#include <netatm/atm.h>
#include <netatm/atm_if.h>
#include <netatm/atm_sap.h>
#include <netatm/atm_sys.h>
#include <netatm/atm_vc.h>
#include <netatm/atm_ioctl.h>
#include <errno.h>
#include <libatm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "atm.h"
#ifndef lint
__RCSID("@(#) $FreeBSD$");
#endif
/*
* Local functions
*/
static int vcc_compare(const void *, const void *);
static int ip_vcc_compare(const void *, const void *);
static int arp_compare(const void *, const void *);
/*
* Process show ARP command
*
* Command format:
* atm show ARP [<ip-addr>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_arp(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t arp_info_len;
struct atminfreq air;
struct air_arp_rsp *arp_info, *arp_info_base;
struct sockaddr_in *sain;
union {
struct sockaddr_in sain;
struct sockaddr sa;
} host_addr;
/*
* Get IP address of specified host name
*/
bzero(&host_addr, sizeof(host_addr));
host_addr.sa.sa_family = AF_INET;
if (argc) {
sain = get_ip_addr(argv[0]);
if (!sain) {
fprintf(stderr, "%s: host \'%s\' not found\n",
prog, argv[0]);
exit(1);
}
host_addr.sain.sin_addr.s_addr = sain->sin_addr.s_addr;
} else {
host_addr.sain.sin_addr.s_addr = INADDR_ANY;
}
/*
* Get ARP information from the kernel
*/
bzero(&air, sizeof(air));
air.air_opcode = AIOCS_INF_ARP;
air.air_arp_addr = host_addr.sa;
arp_info_len = do_info_ioctl(&air, sizeof(struct air_arp_rsp) * 10);
if ((ssize_t)arp_info_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "not an ATM device\n");
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
arp_info_base = arp_info =
(struct air_arp_rsp *) air.air_buf_addr;
/*
* Sort the ARP table
*/
qsort((void *) arp_info,
arp_info_len / sizeof(struct air_arp_rsp),
sizeof(struct air_arp_rsp),
arp_compare);
/*
* Print the relevant information
*/
while (arp_info_len >= sizeof(struct air_arp_rsp)) {
print_arp_info(arp_info);
arp_info++;
arp_info_len -= sizeof(struct air_arp_rsp);
}
/*
* Release the information from the kernel
*/
free(arp_info_base);
}
/*
* Process show ATM ARP server command
*
* Command format:
* atm show arpserver [<interface-name>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_arpserv(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t buf_len, asrv_info_len;
struct atminfreq air;
struct air_asrv_rsp *asrv_info, *asrv_info_base;
/*
* Validate interface name
*/
bzero(air.air_int_intf, sizeof(air.air_int_intf));
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
strcpy(air.air_int_intf, argv[0]);
argc--; argv++;
}
/*
* Get interface information from the kernel
*/
air.air_opcode = AIOCS_INF_ASV;
buf_len = do_info_ioctl(&air, sizeof(struct air_asrv_rsp) * 3);
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
argv[0]);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Print the interface information
*/
asrv_info_base = asrv_info =
(struct air_asrv_rsp *)(void *)air.air_buf_addr;
while (buf_len >= sizeof(struct air_asrv_rsp)) {
print_asrv_info(asrv_info);
asrv_info_len = sizeof(struct air_asrv_rsp) +
asrv_info->asp_nprefix * sizeof(struct in_addr) * 2;
asrv_info = (struct air_asrv_rsp *)(void *)
((char *)asrv_info + asrv_info_len);
buf_len -= asrv_info_len;
}
free(asrv_info_base);
}
/*
* Process show ATM adapter configuration command
*
* Command format:
* atm show config [<interface-name>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_config(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t buf_len;
struct atminfreq air;
struct air_cfg_rsp *cfg_info, *cfg_info_base;
/*
* Validate interface name
*/
bzero(air.air_cfg_intf, sizeof(air.air_cfg_intf));
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
strcpy(air.air_cfg_intf, argv[0]);
argc--; argv++;
}
/*
* Get configuration information from the kernel
*/
air.air_opcode = AIOCS_INF_CFG;
buf_len = do_info_ioctl(&air, sizeof(struct air_asrv_rsp) * 3);
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
argv[0]);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Print the interface information
*/
cfg_info_base = cfg_info =
(struct air_cfg_rsp *)(void *)air.air_buf_addr;
for (; buf_len >= sizeof(struct air_cfg_rsp); cfg_info++,
buf_len -= sizeof(struct air_cfg_rsp)) {
print_cfg_info(cfg_info);
}
free(cfg_info_base);
}
/*
* Process show interface command
*
* Command format:
* atm show interface [<interface-name>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_intf(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t buf_len;
struct atminfreq air;
struct air_int_rsp *int_info, *int_info_base;
/*
* Validate interface name
*/
bzero(&air, sizeof(air));
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
strcpy(air.air_int_intf, argv[0]);
argc--; argv++;
}
/*
* Get interface information from the kernel
*/
air.air_opcode = AIOCS_INF_INT;
buf_len = do_info_ioctl(&air, sizeof(struct air_int_rsp) * 3);
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
argv[0]);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Print the interface information
*/
int_info_base = int_info =
(struct air_int_rsp *)(void *)air.air_buf_addr;
for (; buf_len >= sizeof(struct air_int_rsp); int_info++,
buf_len -= sizeof(struct air_int_rsp)) {
print_intf_info(int_info);
}
free(int_info_base);
}
/*
* Process show IP VCCs command
*
* Command format:
* atm show ipvcc [<ip-addr>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_ip_vcc(int argc, char **argv, const struct cmd *cmdp __unused)
{
int rc;
size_t ip_info_len;
char *if_name = (char *)0;
struct atminfreq air;
struct air_ip_vcc_rsp *ip_info, *ip_info_base;
struct sockaddr_in *sain;
union {
struct sockaddr_in sain;
struct sockaddr sa;
} host_addr;
/*
* First parameter can be a netif name, an IP host name, or
* an IP address. Figure out which it is.
*/
bzero(&host_addr, sizeof(host_addr));
host_addr.sa.sa_family = AF_INET;
if (argc) {
rc = verify_nif_name(argv[0]);
if (rc < 0) {
/*
* Error occured
*/
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
argv[0]);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
} else if (rc > 0) {
/*
* Parameter is a valid netif name
*/
if_name = argv[0];
} else {
/*
* Get IP address of specified host name
*/
sain = get_ip_addr(argv[0]);
host_addr.sain.sin_addr.s_addr =
sain->sin_addr.s_addr;
}
} else {
host_addr.sain.sin_addr.s_addr = INADDR_ANY;
}
/*
* Get IP map information from the kernel
*/
air.air_opcode = AIOCS_INF_IPM;
air.air_ip_addr = host_addr.sa;
ip_info_len = do_info_ioctl(&air, sizeof(struct air_ip_vcc_rsp) * 10);
if ((ssize_t)ip_info_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "not an ATM device\n");
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
ip_info_base = ip_info =
(struct air_ip_vcc_rsp *)(void *)air.air_buf_addr;
/*
* Sort the information
*/
qsort((void *) ip_info,
ip_info_len / sizeof(struct air_ip_vcc_rsp),
sizeof(struct air_ip_vcc_rsp),
ip_vcc_compare);
/*
* Print the relevant information
*/
while (ip_info_len >= sizeof(struct air_ip_vcc_rsp)) {
if (!if_name || !strcmp(if_name, ip_info->aip_intf)) {
print_ip_vcc_info(ip_info);
}
ip_info++;
ip_info_len -= sizeof(struct air_ip_vcc_rsp);
}
/*
* Release the information from the kernel
*/
free(ip_info_base);
}
/*
* Process show network interface command
*
* Command format:
* atm show netif [<netif>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_netif(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t buf_len;
struct atminfreq air;
struct air_netif_rsp *int_info, *int_info_base;
/*
* Validate network interface name
*/
bzero(air.air_int_intf, sizeof(air.air_int_intf));
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n", prog);
exit(1);
}
strcpy(air.air_int_intf, argv[0]);
argc--; argv++;
}
/*
* Get network interface information from the kernel
*/
air.air_opcode = AIOCS_INF_NIF;
buf_len = do_info_ioctl(&air, sizeof(struct air_netif_rsp) * 3);
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
argv[0]);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Print the network interface information
*/
int_info_base = int_info =
(struct air_netif_rsp *) air.air_buf_addr;
for (; buf_len >= sizeof(struct air_netif_rsp); int_info++,
buf_len -= sizeof(struct air_netif_rsp)) {
print_netif_info(int_info);
}
free(int_info_base);
}
/*
* Process interface statistics command
*
* Command format:
* atm show stats interface [<interface-name>]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_intf_stats(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t buf_len;
char intf[IFNAMSIZ];
struct atminfreq air;
struct air_phy_stat_rsp *pstat_info, *pstat_info_base;
struct air_cfg_rsp *cfg_info;
/*
* Validate interface name
*/
bzero(intf, sizeof(intf));
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
strcpy(intf, argv[0]);
argc--; argv++;
}
/*
* If there are parameters remaining, the request is for
* vendor-specific adaptor statistics
*/
if (argc) {
/*
* Get adapter configuration information
*/
air.air_opcode = AIOCS_INF_CFG;
strcpy(air.air_cfg_intf, intf);
buf_len = do_info_ioctl(&air, sizeof(struct air_cfg_rsp));
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
intf);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
cfg_info = (struct air_cfg_rsp *)(void *)air.air_buf_addr;
/*
* Call the appropriate vendor-specific routine
*/
switch(cfg_info->acp_vendor) {
case VENDOR_FORE:
show_fore200_stats(intf, argc, argv);
break;
default:
fprintf(stderr, "%s: Unknown adapter vendor\n",
prog);
break;
}
free(cfg_info);
} else {
/*
* Get generic interface statistics
*/
air.air_opcode = AIOCS_INF_PIS;
strcpy(air.air_physt_intf, intf);
buf_len = do_info_ioctl(&air,
sizeof(struct air_phy_stat_rsp) * 3);
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "%s is not an ATM device\n",
intf);
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Display the interface statistics
*/
pstat_info_base = pstat_info = (struct air_phy_stat_rsp *)
(void *)air.air_buf_addr;
for (; buf_len >= sizeof(struct air_phy_stat_rsp);
pstat_info++,
buf_len-=sizeof(struct air_phy_stat_rsp)) {
print_intf_stats(pstat_info);
}
free((caddr_t)pstat_info_base);
}
}
/*
* Process VCC statistics command
*
* Command format:
* atm show stats VCC [<interface-name> [<vpi> [<vci>]]]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_vcc_stats(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t vcc_info_len;
int vpi = -1, vci = -1;
char *cp, *intf = NULL;
struct air_vcc_rsp *vcc_info, *vcc_info_base;
/*
* Validate interface name
*/
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
intf = argv[0];
argc--; argv++;
}
/*
* Validate VPI value
*/
if (argc) {
vpi = strtol(argv[0], &cp, 0);
if ((*cp != '\0') || (vpi < 0) || (vpi >= 1 << 8)) {
fprintf(stderr, "%s: Invalid VPI value\n", prog);
exit(1);
}
argc--; argv++;
}
/*
* Validate VCI value
*/
if (argc) {
vci = strtol(argv[0], &cp, 0);
if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
fprintf(stderr, "%s: Invalid VCI value\n",
prog);
exit(1);
}
argc--; argv++;
}
/*
* Get VCC information
*/
vcc_info_len = get_vcc_info(intf, &vcc_info);
if (vcc_info_len == 0)
exit(1);
else if ((ssize_t)vcc_info_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "Not an ATM device\n");
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Sort the VCC information
*/
qsort((void *) vcc_info,
vcc_info_len / sizeof(struct air_vcc_rsp),
sizeof(struct air_vcc_rsp),
vcc_compare);
/*
* Display the VCC statistics
*/
vcc_info_base = vcc_info;
for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
vcc_info_len-=sizeof(struct air_vcc_rsp),
vcc_info++) {
if (vpi != -1 && vcc_info->avp_vpi != vpi)
continue;
if (vci != -1 && vcc_info->avp_vci != vci)
continue;
print_vcc_stats(vcc_info);
}
free(vcc_info_base);
}
/*
* Process VCC information command
*
* Command format:
* atm show VCC [<interface-name> [<vpi> [<vci>] | PVC | SVC]]
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_vcc(int argc, char **argv, const struct cmd *cmdp __unused)
{
size_t vcc_info_len;
int vpi = -1, vci = -1, show_pvc = 0, show_svc = 0;
char *cp, *intf = NULL;
struct air_vcc_rsp *vcc_info, *vcc_info_base;
/*
* Validate interface name
*/
if (argc) {
if (strlen(argv[0]) > IFNAMSIZ - 1) {
fprintf(stderr, "%s: Illegal interface name\n",
prog);
exit(1);
}
intf = argv[0];
argc--; argv++;
}
/*
* Validate VPI value
*/
if (argc) {
if (strcasecmp(argv[0], "pvc"))
show_pvc = 1;
else if (strcasecmp(argv[0], "svc"))
show_svc = 1;
else {
vpi = strtol(argv[0], &cp, 0);
if ((*cp != '\0') || (vpi < 0) ||
(vpi >= 1 << 8)) {
fprintf(stderr, "%s: Invalid VPI value\n", prog);
exit(1);
}
}
argc--; argv++;
}
/*
* Validate VCI value
*/
if (argc) {
vci = strtol(argv[0], &cp, 0);
if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
fprintf(stderr, "%s: Invalid VCI value\n",
prog);
exit(1);
}
argc--; argv++;
}
/*
* Get VCC information
*/
vcc_info_len = get_vcc_info(intf, &vcc_info);
if (vcc_info_len == 0)
exit(1);
else if ((ssize_t)vcc_info_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "Not an ATM device\n");
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Sort the VCC information
*/
qsort((void *) vcc_info,
vcc_info_len/sizeof(struct air_vcc_rsp),
sizeof(struct air_vcc_rsp),
vcc_compare);
/*
* Display the VCC information
*/
vcc_info_base = vcc_info;
for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
vcc_info_len-=sizeof(struct air_vcc_rsp),
vcc_info++) {
if (vpi != -1 && vcc_info->avp_vpi != vpi)
continue;
if (vci != -1 && vcc_info->avp_vci != vci)
continue;
if (show_pvc && vcc_info->avp_type & VCC_PVC)
continue;
if (show_svc && vcc_info->avp_type & VCC_SVC)
continue;
print_vcc_info(vcc_info);
}
free(vcc_info_base);
}
/*
* Process version command
*
* Command format:
* atm show version
*
* Arguments:
* argc number of remaining arguments to command
* argv pointer to remaining argument strings
* cmdp pointer to command description
*
* Returns:
* none
*
*/
void
show_version(int argc __unused, char **argv __unused,
const struct cmd *cmdp __unused)
{
size_t buf_len;
struct atminfreq air;
struct air_version_rsp *ver_info, *ver_info_base;
/*
* Get network interface information from the kernel
*/
air.air_opcode = AIOCS_INF_VER;
buf_len = do_info_ioctl(&air, sizeof(struct air_version_rsp));
if ((ssize_t)buf_len == -1) {
fprintf(stderr, "%s: ", prog);
switch (errno) {
case ENOPROTOOPT:
case EOPNOTSUPP:
perror("Internal error");
break;
case ENXIO:
fprintf(stderr, "Not an ATM device\n");
break;
default:
perror("ioctl (AIOCINFO)");
break;
}
exit(1);
}
/*
* Print the network interface information
*/
ver_info_base = ver_info =
(struct air_version_rsp *)(void *)air.air_buf_addr;
for (; buf_len >= sizeof(struct air_version_rsp); ver_info++,
buf_len -= sizeof(struct air_version_rsp)) {
print_version_info(ver_info);
}
free(ver_info_base);
}
/*
* Comparison function for qsort
*
* Arguments:
* p1 pointer to the first VCC response
* p2 pointer to the second VCC response
*
* Returns:
* int a number less than, greater than, or equal to zero,
* depending on whether *p1 is less than, greater than, or
* equal to *p2
*
*/
static int
vcc_compare(p1, p2)
const void *p1, *p2;
{
int rc;
const struct air_vcc_rsp *c1, *c2;
c1 = (const struct air_vcc_rsp *) p1;
c2 = (const struct air_vcc_rsp *) p2;
/*
* Compare the interface names
*/
rc = strcmp(c1->avp_intf, c2->avp_intf);
if (rc)
return(rc);
/*
* Compare the VPI values
*/
rc = c1->avp_vpi - c2->avp_vpi;
if (rc)
return(rc);
/*
* Compare the VCI values
*/
rc = c1->avp_vci - c2->avp_vci;
if (rc)
return(rc);
/*
* Compare the types
*/
rc = c1->avp_type - c2->avp_type;
return(rc);
}
/*
* Comparison function for qsort
*
* Arguments:
* p1 pointer to the first VCC response
* p2 pointer to the second VCC response
*
* Returns:
* int a number less than, greater than, or equal to zero,
* depending on whether *p1 is less than, greater than, or
* equal to *p2
*
*/
static int
ip_vcc_compare(p1, p2)
const void *p1, *p2;
{
int rc;
const struct air_ip_vcc_rsp *c1, *c2;
c1 = (const struct air_ip_vcc_rsp *) p1;
c2 = (const struct air_ip_vcc_rsp *) p2;
/*
* Compare the interface names
*/
rc = strcmp(c1->aip_intf, c2->aip_intf);
if (rc)
return(rc);
/*
* Compare the VPI values
*/
rc = c1->aip_vpi - c2->aip_vpi;
if (rc)
return(rc);
/*
* Compare the VCI values
*/
rc = c1->aip_vci - c2->aip_vci;
return(rc);
}
/*
* Comparison function for qsort
*
* Arguments:
* p1 pointer to the first ARP or IP map entry
* p2 pointer to the second ARP or IP map entry
*
* Returns:
* int a number less than, greater than, or equal to zero,
* depending on whether *p1 is less than, greater than, or
* equal to *p2
*
*/
static int
arp_compare(p1, p2)
const void *p1, *p2;
{
int rc;
const struct air_arp_rsp *c1, *c2;
const struct sockaddr_in *sin1, *sin2;
c1 = (const struct air_arp_rsp *)p1;
c2 = (const struct air_arp_rsp *)p2;
sin1 = (const struct sockaddr_in *)(const void *)&c1->aap_arp_addr;
sin2 = (const struct sockaddr_in *)(const void *)&c2->aap_arp_addr;
/*
* Compare the IP addresses
*/
if ((rc = sin1->sin_family - sin2->sin_family) != 0)
return(rc);
if ((rc = sin1->sin_addr.s_addr - sin2->sin_addr.s_addr) != 0)
return(rc);
/*
* Compare the ATM addresses
*/
if ((rc = c1->aap_addr.address_format - c2->aap_addr.address_format) != 0)
return(rc);
if ((rc = c1->aap_addr.address_length - c2->aap_addr.address_length) != 0)
return(rc);
switch(c1->aap_addr.address_format) {
case T_ATM_ABSENT:
rc = 0;
break;
case T_ATM_ENDSYS_ADDR:
rc = bcmp(c1->aap_addr.address, c2->aap_addr.address,
sizeof(Atm_addr_nsap));
break;
case T_ATM_E164_ADDR:
rc = bcmp(c1->aap_addr.address, c2->aap_addr.address,
sizeof(Atm_addr_e164));
break;
case T_ATM_SPANS_ADDR:
rc = bcmp(c1->aap_addr.address, c2->aap_addr.address,
sizeof(Atm_addr_spans));
break;
}
return(rc);
}