3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sbin/atm/atm/atm_show.c,v 1.3.2.1 2000/07/01 06:02:14 ps Exp $
31 * User configuration and display program
32 * --------------------------------------
34 * Routines for "show" subcommand
38 #include <sys/param.h>
39 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <netatm/port.h>
43 #include <netatm/atm.h>
44 #include <netatm/atm_if.h>
45 #include <netatm/atm_sap.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_vc.h>
48 #include <netatm/atm_ioctl.h>
59 __RCSID("@(#) $FreeBSD: src/sbin/atm/atm/atm_show.c,v 1.3.2.1 2000/07/01 06:02:14 ps Exp $");
66 static int vcc_compare __P((const void *, const void *));
67 static int ip_vcc_compare __P((const void *, const void *));
68 static int arp_compare __P((const void *, const void *));
72 * Process show ARP command
75 * atm show ARP [<ip-addr>]
78 * argc number of remaining arguments to command
79 * argv pointer to remaining argument strings
80 * cmdp pointer to command description
87 show_arp(argc, argv, cmdp)
92 int buf_len, arp_info_len;
94 struct air_arp_rsp *arp_info, *arp_info_base;
95 struct sockaddr_in *sin;
97 struct sockaddr_in sin;
102 * Get IP address of specified host name
104 UM_ZERO(&host_addr, sizeof(host_addr));
105 host_addr.sa.sa_family = AF_INET;
107 sin = get_ip_addr(argv[0]);
109 fprintf(stderr, "%s: host \'%s\' not found\n",
113 host_addr.sin.sin_addr.s_addr = sin->sin_addr.s_addr;
115 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
119 * Get ARP information from the kernel
121 UM_ZERO(&air, sizeof(air));
122 buf_len = sizeof(struct air_arp_rsp) * 10;
123 air.air_opcode = AIOCS_INF_ARP;
124 air.air_arp_addr = host_addr.sa;
125 arp_info_len = do_info_ioctl(&air, buf_len);
126 if (arp_info_len < 0) {
127 fprintf(stderr, "%s: ", prog);
131 perror("Internal error");
134 fprintf(stderr, "not an ATM device\n");
137 perror("ioctl (AIOCINFO)");
142 arp_info_base = arp_info =
143 (struct air_arp_rsp *) air.air_buf_addr;
148 qsort((void *) arp_info,
149 arp_info_len / sizeof(struct air_arp_rsp),
150 sizeof(struct air_arp_rsp),
154 * Print the relevant information
156 while (arp_info_len > 0) {
157 print_arp_info(arp_info);
159 arp_info_len -= sizeof(struct air_arp_rsp);
163 * Release the information from the kernel
165 UM_FREE(arp_info_base);
170 * Process show ATM ARP server command
173 * atm show arpserver [<interface-name>]
176 * argc number of remaining arguments to command
177 * argv pointer to remaining argument strings
178 * cmdp pointer to command description
185 show_arpserv(argc, argv, cmdp)
190 int asrv_info_len, buf_len = sizeof(struct air_asrv_rsp) * 3;
191 struct atminfreq air;
192 struct air_asrv_rsp *asrv_info, *asrv_info_base;
195 * Validate interface name
197 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
199 if (strlen(argv[0]) > IFNAMSIZ - 1) {
200 fprintf(stderr, "%s: Illegal interface name\n",
204 strcpy(air.air_int_intf, argv[0]);
209 * Get interface information from the kernel
211 air.air_opcode = AIOCS_INF_ASV;
212 buf_len = do_info_ioctl(&air, buf_len);
214 fprintf(stderr, "%s: ", prog);
218 perror("Internal error");
221 fprintf(stderr, "%s is not an ATM device\n",
225 perror("ioctl (AIOCINFO)");
232 * Print the interface information
234 asrv_info_base = asrv_info =
235 (struct air_asrv_rsp *) air.air_buf_addr;
236 for (; buf_len >= sizeof(struct air_asrv_rsp);
237 asrv_info = (struct air_asrv_rsp *)
238 ((u_long)asrv_info + asrv_info_len),
239 buf_len -= asrv_info_len) {
240 print_asrv_info(asrv_info);
241 asrv_info_len = sizeof(struct air_asrv_rsp) +
242 asrv_info->asp_nprefix *
243 sizeof(struct in_addr) * 2;
245 UM_FREE(asrv_info_base);
250 * Process show ATM adapter configuration command
253 * atm show config [<interface-name>]
256 * argc number of remaining arguments to command
257 * argv pointer to remaining argument strings
258 * cmdp pointer to command description
265 show_config(argc, argv, cmdp)
270 int buf_len = sizeof(struct air_asrv_rsp) * 3;
271 struct atminfreq air;
272 struct air_cfg_rsp *cfg_info, *cfg_info_base;
275 * Validate interface name
277 UM_ZERO(air.air_cfg_intf, sizeof(air.air_cfg_intf));
279 if (strlen(argv[0]) > IFNAMSIZ - 1) {
280 fprintf(stderr, "%s: Illegal interface name\n",
284 strcpy(air.air_cfg_intf, argv[0]);
289 * Get configuration information from the kernel
291 air.air_opcode = AIOCS_INF_CFG;
292 buf_len = do_info_ioctl(&air, buf_len);
294 fprintf(stderr, "%s: ", prog);
298 perror("Internal error");
301 fprintf(stderr, "%s is not an ATM device\n",
305 perror("ioctl (AIOCINFO)");
312 * Print the interface information
314 cfg_info_base = cfg_info =
315 (struct air_cfg_rsp *) air.air_buf_addr;
316 for (; buf_len >= sizeof(struct air_cfg_rsp); cfg_info++,
317 buf_len -= sizeof(struct air_cfg_rsp)) {
318 print_cfg_info(cfg_info);
320 UM_FREE(cfg_info_base);
325 * Process show interface command
328 * atm show interface [<interface-name>]
331 * argc number of remaining arguments to command
332 * argv pointer to remaining argument strings
333 * cmdp pointer to command description
340 show_intf(argc, argv, cmdp)
345 int buf_len = sizeof(struct air_int_rsp) * 3;
346 struct atminfreq air;
347 struct air_int_rsp *int_info, *int_info_base;
350 * Validate interface name
352 UM_ZERO(&air, sizeof(air));
354 if (strlen(argv[0]) > IFNAMSIZ - 1) {
355 fprintf(stderr, "%s: Illegal interface name\n",
359 strcpy(air.air_int_intf, argv[0]);
364 * Get interface information from the kernel
366 air.air_opcode = AIOCS_INF_INT;
367 buf_len = do_info_ioctl(&air, buf_len);
369 fprintf(stderr, "%s: ", prog);
373 perror("Internal error");
376 fprintf(stderr, "%s is not an ATM device\n",
380 perror("ioctl (AIOCINFO)");
387 * Print the interface information
389 int_info_base = int_info =
390 (struct air_int_rsp *) air.air_buf_addr;
391 for (; buf_len >= sizeof(struct air_int_rsp); int_info++,
392 buf_len -= sizeof(struct air_int_rsp)) {
393 print_intf_info(int_info);
395 UM_FREE(int_info_base);
400 * Process show IP VCCs command
403 * atm show ipvcc [<ip-addr>]
406 * argc number of remaining arguments to command
407 * argv pointer to remaining argument strings
408 * cmdp pointer to command description
415 show_ip_vcc(argc, argv, cmdp)
420 int buf_len, ip_info_len, rc;
421 char *if_name = (char *)0;
422 struct atminfreq air;
423 struct air_ip_vcc_rsp *ip_info, *ip_info_base;
424 struct sockaddr_in *sin;
426 struct sockaddr_in sin;
431 * First parameter can be a netif name, an IP host name, or
432 * an IP address. Figure out which it is.
434 UM_ZERO(&host_addr, sizeof(host_addr));
435 host_addr.sa.sa_family = AF_INET;
437 rc = verify_nif_name(argv[0]);
442 fprintf(stderr, "%s: ", prog);
446 perror("Internal error");
449 fprintf(stderr, "%s is not an ATM device\n",
453 perror("ioctl (AIOCINFO)");
459 * Parameter is a valid netif name
464 * Get IP address of specified host name
466 sin = get_ip_addr(argv[0]);
467 host_addr.sin.sin_addr.s_addr =
468 sin->sin_addr.s_addr;
471 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
475 * Get IP map information from the kernel
477 buf_len = sizeof(struct air_ip_vcc_rsp) * 10;
478 air.air_opcode = AIOCS_INF_IPM;
479 air.air_ip_addr = host_addr.sa;
480 ip_info_len = do_info_ioctl(&air, buf_len);
481 if (ip_info_len < 0) {
482 fprintf(stderr, "%s: ", prog);
486 perror("Internal error");
489 fprintf(stderr, "not an ATM device\n");
492 perror("ioctl (AIOCINFO)");
497 ip_info_base = ip_info =
498 (struct air_ip_vcc_rsp *) air.air_buf_addr;
501 * Sort the information
503 qsort((void *) ip_info,
504 ip_info_len / sizeof(struct air_ip_vcc_rsp),
505 sizeof(struct air_ip_vcc_rsp),
509 * Print the relevant information
511 while (ip_info_len>0) {
512 if (!if_name || !strcmp(if_name, ip_info->aip_intf)) {
513 print_ip_vcc_info(ip_info);
516 ip_info_len -= sizeof(struct air_ip_vcc_rsp);
520 * Release the information from the kernel
522 UM_FREE(ip_info_base);
528 * Process show network interface command
531 * atm show netif [<netif>]
534 * argc number of remaining arguments to command
535 * argv pointer to remaining argument strings
536 * cmdp pointer to command description
543 show_netif(argc, argv, cmdp)
548 int buf_len = sizeof(struct air_netif_rsp) * 3;
549 struct atminfreq air;
550 struct air_netif_rsp *int_info, *int_info_base;
553 * Validate network interface name
555 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
557 if (strlen(argv[0]) > IFNAMSIZ - 1) {
558 fprintf(stderr, "%s: Illegal interface name\n", prog);
561 strcpy(air.air_int_intf, argv[0]);
566 * Get network interface information from the kernel
568 air.air_opcode = AIOCS_INF_NIF;
569 buf_len = do_info_ioctl(&air, buf_len);
571 fprintf(stderr, "%s: ", prog);
575 perror("Internal error");
578 fprintf(stderr, "%s is not an ATM device\n",
582 perror("ioctl (AIOCINFO)");
589 * Print the network interface information
591 int_info_base = int_info =
592 (struct air_netif_rsp *) air.air_buf_addr;
593 for (; buf_len >= sizeof(struct air_netif_rsp); int_info++,
594 buf_len -= sizeof(struct air_netif_rsp)) {
595 print_netif_info(int_info);
597 UM_FREE(int_info_base);
602 * Process interface statistics command
605 * atm show stats interface [<interface-name>]
608 * argc number of remaining arguments to command
609 * argv pointer to remaining argument strings
610 * cmdp pointer to command description
617 show_intf_stats(argc, argv, cmdp)
624 struct atminfreq air;
625 struct air_phy_stat_rsp *pstat_info, *pstat_info_base;
626 struct air_cfg_rsp *cfg_info;
629 * Validate interface name
631 UM_ZERO(intf, sizeof(intf));
633 if (strlen(argv[0]) > IFNAMSIZ - 1) {
634 fprintf(stderr, "%s: Illegal interface name\n",
638 strcpy(intf, argv[0]);
643 * If there are parameters remaining, the request is for
644 * vendor-specific adaptor statistics
648 * Get adapter configuration information
650 buf_len = sizeof(struct air_cfg_rsp);
651 air.air_opcode = AIOCS_INF_CFG;
652 strcpy(air.air_cfg_intf, intf);
653 buf_len = do_info_ioctl(&air, buf_len);
655 fprintf(stderr, "%s: ", prog);
659 perror("Internal error");
662 fprintf(stderr, "%s is not an ATM device\n",
666 perror("ioctl (AIOCINFO)");
671 cfg_info = (struct air_cfg_rsp *)air.air_buf_addr;
674 * Call the appropriate vendor-specific routine
676 switch(cfg_info->acp_vendor) {
678 show_fore200_stats(intf, argc, argv);
681 show_eni_stats(intf, argc, argv);
684 fprintf(stderr, "%s: Unknown adapter vendor\n",
692 * Get generic interface statistics
694 buf_len = sizeof(struct air_phy_stat_rsp) * 3;
695 air.air_opcode = AIOCS_INF_PIS;
696 strcpy(air.air_physt_intf, intf);
697 buf_len = do_info_ioctl(&air, buf_len);
699 fprintf(stderr, "%s: ", prog);
703 perror("Internal error");
706 fprintf(stderr, "%s is not an ATM device\n",
710 perror("ioctl (AIOCINFO)");
717 * Display the interface statistics
719 pstat_info_base = pstat_info =
720 (struct air_phy_stat_rsp *)air.air_buf_addr;
721 for (; buf_len >= sizeof(struct air_phy_stat_rsp);
723 buf_len-=sizeof(struct air_phy_stat_rsp)) {
724 print_intf_stats(pstat_info);
726 UM_FREE((caddr_t)pstat_info_base);
732 * Process VCC statistics command
735 * atm show stats VCC [<interface-name> [<vpi> [<vci>]]]
738 * argc number of remaining arguments to command
739 * argv pointer to remaining argument strings
740 * cmdp pointer to command description
747 show_vcc_stats(argc, argv, cmdp)
753 int vpi = -1, vci = -1;
754 char *cp, *intf = NULL;
755 struct air_vcc_rsp *vcc_info, *vcc_info_base;
758 * Validate interface name
761 if (strlen(argv[0]) > IFNAMSIZ - 1) {
762 fprintf(stderr, "%s: Illegal interface name\n",
774 vpi = strtol(argv[0], &cp, 0);
775 if ((*cp != '\0') || (vpi < 0) || (vpi >= 1 << 8)) {
776 fprintf(stderr, "%s: Invalid VPI value\n", prog);
786 vci = strtol(argv[0], &cp, 0);
787 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
788 fprintf(stderr, "%s: Invalid VCI value\n",
796 * Get VCC information
798 vcc_info_len = get_vcc_info(intf, &vcc_info);
799 if (vcc_info_len == 0)
801 else if (vcc_info_len < 0) {
802 fprintf(stderr, "%s: ", prog);
806 perror("Internal error");
809 fprintf(stderr, "Not an ATM device\n");
812 perror("ioctl (AIOCINFO)");
819 * Sort the VCC information
821 qsort((void *) vcc_info,
822 vcc_info_len / sizeof(struct air_vcc_rsp),
823 sizeof(struct air_vcc_rsp),
827 * Display the VCC statistics
829 vcc_info_base = vcc_info;
830 for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
831 vcc_info_len-=sizeof(struct air_vcc_rsp),
833 if (vpi != -1 && vcc_info->avp_vpi != vpi)
835 if (vci != -1 && vcc_info->avp_vci != vci)
837 print_vcc_stats(vcc_info);
839 UM_FREE(vcc_info_base);
844 * Process VCC information command
847 * atm show VCC [<interface-name> [<vpi> [<vci>] | PVC | SVC]]
850 * argc number of remaining arguments to command
851 * argv pointer to remaining argument strings
852 * cmdp pointer to command description
859 show_vcc(argc, argv, cmdp)
865 int vpi = -1, vci = -1, show_pvc = 0, show_svc = 0;
866 char *cp, *intf = NULL;
867 struct air_vcc_rsp *vcc_info, *vcc_info_base;
870 * Validate interface name
873 if (strlen(argv[0]) > IFNAMSIZ - 1) {
874 fprintf(stderr, "%s: Illegal interface name\n",
886 if (strcasecmp(argv[0], "pvc"))
888 else if (strcasecmp(argv[0], "svc"))
891 vpi = strtol(argv[0], &cp, 0);
892 if ((*cp != '\0') || (vpi < 0) ||
894 fprintf(stderr, "%s: Invalid VPI value\n", prog);
905 vci = strtol(argv[0], &cp, 0);
906 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
907 fprintf(stderr, "%s: Invalid VCI value\n",
915 * Get VCC information
917 vcc_info_len = get_vcc_info(intf, &vcc_info);
918 if (vcc_info_len == 0)
920 else if (vcc_info_len < 0) {
921 fprintf(stderr, "%s: ", prog);
925 perror("Internal error");
928 fprintf(stderr, "Not an ATM device\n");
931 perror("ioctl (AIOCINFO)");
938 * Sort the VCC information
940 qsort((void *) vcc_info,
941 vcc_info_len/sizeof(struct air_vcc_rsp),
942 sizeof(struct air_vcc_rsp),
946 * Display the VCC information
948 vcc_info_base = vcc_info;
949 for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
950 vcc_info_len-=sizeof(struct air_vcc_rsp),
952 if (vpi != -1 && vcc_info->avp_vpi != vpi)
954 if (vci != -1 && vcc_info->avp_vci != vci)
956 if (show_pvc && vcc_info->avp_type & VCC_PVC)
958 if (show_svc && vcc_info->avp_type & VCC_SVC)
960 print_vcc_info(vcc_info);
962 UM_FREE(vcc_info_base);
967 * Process version command
973 * argc number of remaining arguments to command
974 * argv pointer to remaining argument strings
975 * cmdp pointer to command description
982 show_version(argc, argv, cmdp)
987 int buf_len = sizeof(struct air_version_rsp);
988 struct atminfreq air;
989 struct air_version_rsp *ver_info, *ver_info_base;
992 * Get network interface information from the kernel
994 air.air_opcode = AIOCS_INF_VER;
995 buf_len = do_info_ioctl(&air, buf_len);
997 fprintf(stderr, "%s: ", prog);
1001 perror("Internal error");
1004 fprintf(stderr, "Not an ATM device\n");
1007 perror("ioctl (AIOCINFO)");
1014 * Print the network interface information
1016 ver_info_base = ver_info =
1017 (struct air_version_rsp *) air.air_buf_addr;
1018 for (; buf_len >= sizeof(struct air_version_rsp); ver_info++,
1019 buf_len -= sizeof(struct air_version_rsp)) {
1020 print_version_info(ver_info);
1022 UM_FREE(ver_info_base);
1027 * Comparison function for qsort
1030 * p1 pointer to the first VCC response
1031 * p2 pointer to the second VCC response
1034 * int a number less than, greater than, or equal to zero,
1035 * depending on whether *p1 is less than, greater than, or
1041 const void *p1, *p2;
1044 struct air_vcc_rsp *c1, *c2;
1046 c1 = (struct air_vcc_rsp *) p1;
1047 c2 = (struct air_vcc_rsp *) p2;
1050 * Compare the interface names
1052 rc = strcmp(c1->avp_intf, c2->avp_intf);
1057 * Compare the VPI values
1059 rc = c1->avp_vpi - c2->avp_vpi;
1064 * Compare the VCI values
1066 rc = c1->avp_vci - c2->avp_vci;
1073 rc = c1->avp_type - c2->avp_type;
1079 * Comparison function for qsort
1082 * p1 pointer to the first VCC response
1083 * p2 pointer to the second VCC response
1086 * int a number less than, greater than, or equal to zero,
1087 * depending on whether *p1 is less than, greater than, or
1092 ip_vcc_compare(p1, p2)
1093 const void *p1, *p2;
1096 struct air_ip_vcc_rsp *c1, *c2;
1098 c1 = (struct air_ip_vcc_rsp *) p1;
1099 c2 = (struct air_ip_vcc_rsp *) p2;
1102 * Compare the interface names
1104 rc = strcmp(c1->aip_intf, c2->aip_intf);
1109 * Compare the VPI values
1111 rc = c1->aip_vpi - c2->aip_vpi;
1116 * Compare the VCI values
1118 rc = c1->aip_vci - c2->aip_vci;
1124 * Comparison function for qsort
1127 * p1 pointer to the first ARP or IP map entry
1128 * p2 pointer to the second ARP or IP map entry
1131 * int a number less than, greater than, or equal to zero,
1132 * depending on whether *p1 is less than, greater than, or
1138 const void *p1, *p2;
1141 struct air_arp_rsp *c1, *c2;
1142 struct sockaddr_in *sin1, *sin2;
1144 c1 = (struct air_arp_rsp *) p1;
1145 c2 = (struct air_arp_rsp *) p2;
1146 sin1 = (struct sockaddr_in *) &c1->aap_arp_addr;
1147 sin2 = (struct sockaddr_in *) &c2->aap_arp_addr;
1150 * Compare the IP addresses
1152 if ((rc = sin1->sin_family - sin2->sin_family) != 0)
1154 if ((rc = sin1->sin_addr.s_addr - sin2->sin_addr.s_addr) != 0)
1158 * Compare the ATM addresses
1160 if ((rc = c1->aap_addr.address_format - c2->aap_addr.address_format) != 0)
1162 if ((rc = c1->aap_addr.address_length - c2->aap_addr.address_length) != 0)
1164 switch(c1->aap_addr.address_format) {
1168 case T_ATM_ENDSYS_ADDR:
1169 rc = bcmp((caddr_t)c1->aap_addr.address,
1170 (caddr_t)c2->aap_addr.address,
1171 sizeof(Atm_addr_nsap));
1173 case T_ATM_E164_ADDR:
1174 rc = bcmp((caddr_t)c1->aap_addr.address,
1175 (caddr_t)c2->aap_addr.address,
1176 sizeof(Atm_addr_e164));
1178 case T_ATM_SPANS_ADDR:
1179 rc = bcmp((caddr_t)c1->aap_addr.address,
1180 (caddr_t)c2->aap_addr.address,
1181 sizeof(Atm_addr_spans));