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 $
27 * @(#) $DragonFly: src/sbin/atm/atm/atm_show.c,v 1.2 2003/06/17 04:27:32 dillon 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>
61 static int vcc_compare __P((const void *, const void *));
62 static int ip_vcc_compare __P((const void *, const void *));
63 static int arp_compare __P((const void *, const void *));
67 * Process show ARP command
70 * atm show ARP [<ip-addr>]
73 * argc number of remaining arguments to command
74 * argv pointer to remaining argument strings
75 * cmdp pointer to command description
82 show_arp(argc, argv, cmdp)
87 int buf_len, arp_info_len;
89 struct air_arp_rsp *arp_info, *arp_info_base;
90 struct sockaddr_in *sin;
92 struct sockaddr_in sin;
97 * Get IP address of specified host name
99 UM_ZERO(&host_addr, sizeof(host_addr));
100 host_addr.sa.sa_family = AF_INET;
102 sin = get_ip_addr(argv[0]);
104 fprintf(stderr, "%s: host \'%s\' not found\n",
108 host_addr.sin.sin_addr.s_addr = sin->sin_addr.s_addr;
110 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
114 * Get ARP information from the kernel
116 UM_ZERO(&air, sizeof(air));
117 buf_len = sizeof(struct air_arp_rsp) * 10;
118 air.air_opcode = AIOCS_INF_ARP;
119 air.air_arp_addr = host_addr.sa;
120 arp_info_len = do_info_ioctl(&air, buf_len);
121 if (arp_info_len < 0) {
122 fprintf(stderr, "%s: ", prog);
126 perror("Internal error");
129 fprintf(stderr, "not an ATM device\n");
132 perror("ioctl (AIOCINFO)");
137 arp_info_base = arp_info =
138 (struct air_arp_rsp *) air.air_buf_addr;
143 qsort((void *) arp_info,
144 arp_info_len / sizeof(struct air_arp_rsp),
145 sizeof(struct air_arp_rsp),
149 * Print the relevant information
151 while (arp_info_len > 0) {
152 print_arp_info(arp_info);
154 arp_info_len -= sizeof(struct air_arp_rsp);
158 * Release the information from the kernel
160 UM_FREE(arp_info_base);
165 * Process show ATM ARP server command
168 * atm show arpserver [<interface-name>]
171 * argc number of remaining arguments to command
172 * argv pointer to remaining argument strings
173 * cmdp pointer to command description
180 show_arpserv(argc, argv, cmdp)
185 int asrv_info_len, buf_len = sizeof(struct air_asrv_rsp) * 3;
186 struct atminfreq air;
187 struct air_asrv_rsp *asrv_info, *asrv_info_base;
190 * Validate interface name
192 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
194 if (strlen(argv[0]) > IFNAMSIZ - 1) {
195 fprintf(stderr, "%s: Illegal interface name\n",
199 strcpy(air.air_int_intf, argv[0]);
204 * Get interface information from the kernel
206 air.air_opcode = AIOCS_INF_ASV;
207 buf_len = do_info_ioctl(&air, buf_len);
209 fprintf(stderr, "%s: ", prog);
213 perror("Internal error");
216 fprintf(stderr, "%s is not an ATM device\n",
220 perror("ioctl (AIOCINFO)");
227 * Print the interface information
229 asrv_info_base = asrv_info =
230 (struct air_asrv_rsp *) air.air_buf_addr;
231 for (; buf_len >= sizeof(struct air_asrv_rsp);
232 asrv_info = (struct air_asrv_rsp *)
233 ((u_long)asrv_info + asrv_info_len),
234 buf_len -= asrv_info_len) {
235 print_asrv_info(asrv_info);
236 asrv_info_len = sizeof(struct air_asrv_rsp) +
237 asrv_info->asp_nprefix *
238 sizeof(struct in_addr) * 2;
240 UM_FREE(asrv_info_base);
245 * Process show ATM adapter configuration command
248 * atm show config [<interface-name>]
251 * argc number of remaining arguments to command
252 * argv pointer to remaining argument strings
253 * cmdp pointer to command description
260 show_config(argc, argv, cmdp)
265 int buf_len = sizeof(struct air_asrv_rsp) * 3;
266 struct atminfreq air;
267 struct air_cfg_rsp *cfg_info, *cfg_info_base;
270 * Validate interface name
272 UM_ZERO(air.air_cfg_intf, sizeof(air.air_cfg_intf));
274 if (strlen(argv[0]) > IFNAMSIZ - 1) {
275 fprintf(stderr, "%s: Illegal interface name\n",
279 strcpy(air.air_cfg_intf, argv[0]);
284 * Get configuration information from the kernel
286 air.air_opcode = AIOCS_INF_CFG;
287 buf_len = do_info_ioctl(&air, buf_len);
289 fprintf(stderr, "%s: ", prog);
293 perror("Internal error");
296 fprintf(stderr, "%s is not an ATM device\n",
300 perror("ioctl (AIOCINFO)");
307 * Print the interface information
309 cfg_info_base = cfg_info =
310 (struct air_cfg_rsp *) air.air_buf_addr;
311 for (; buf_len >= sizeof(struct air_cfg_rsp); cfg_info++,
312 buf_len -= sizeof(struct air_cfg_rsp)) {
313 print_cfg_info(cfg_info);
315 UM_FREE(cfg_info_base);
320 * Process show interface command
323 * atm show interface [<interface-name>]
326 * argc number of remaining arguments to command
327 * argv pointer to remaining argument strings
328 * cmdp pointer to command description
335 show_intf(argc, argv, cmdp)
340 int buf_len = sizeof(struct air_int_rsp) * 3;
341 struct atminfreq air;
342 struct air_int_rsp *int_info, *int_info_base;
345 * Validate interface name
347 UM_ZERO(&air, sizeof(air));
349 if (strlen(argv[0]) > IFNAMSIZ - 1) {
350 fprintf(stderr, "%s: Illegal interface name\n",
354 strcpy(air.air_int_intf, argv[0]);
359 * Get interface information from the kernel
361 air.air_opcode = AIOCS_INF_INT;
362 buf_len = do_info_ioctl(&air, buf_len);
364 fprintf(stderr, "%s: ", prog);
368 perror("Internal error");
371 fprintf(stderr, "%s is not an ATM device\n",
375 perror("ioctl (AIOCINFO)");
382 * Print the interface information
384 int_info_base = int_info =
385 (struct air_int_rsp *) air.air_buf_addr;
386 for (; buf_len >= sizeof(struct air_int_rsp); int_info++,
387 buf_len -= sizeof(struct air_int_rsp)) {
388 print_intf_info(int_info);
390 UM_FREE(int_info_base);
395 * Process show IP VCCs command
398 * atm show ipvcc [<ip-addr>]
401 * argc number of remaining arguments to command
402 * argv pointer to remaining argument strings
403 * cmdp pointer to command description
410 show_ip_vcc(argc, argv, cmdp)
415 int buf_len, ip_info_len, rc;
416 char *if_name = (char *)0;
417 struct atminfreq air;
418 struct air_ip_vcc_rsp *ip_info, *ip_info_base;
419 struct sockaddr_in *sin;
421 struct sockaddr_in sin;
426 * First parameter can be a netif name, an IP host name, or
427 * an IP address. Figure out which it is.
429 UM_ZERO(&host_addr, sizeof(host_addr));
430 host_addr.sa.sa_family = AF_INET;
432 rc = verify_nif_name(argv[0]);
437 fprintf(stderr, "%s: ", prog);
441 perror("Internal error");
444 fprintf(stderr, "%s is not an ATM device\n",
448 perror("ioctl (AIOCINFO)");
454 * Parameter is a valid netif name
459 * Get IP address of specified host name
461 sin = get_ip_addr(argv[0]);
462 host_addr.sin.sin_addr.s_addr =
463 sin->sin_addr.s_addr;
466 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
470 * Get IP map information from the kernel
472 buf_len = sizeof(struct air_ip_vcc_rsp) * 10;
473 air.air_opcode = AIOCS_INF_IPM;
474 air.air_ip_addr = host_addr.sa;
475 ip_info_len = do_info_ioctl(&air, buf_len);
476 if (ip_info_len < 0) {
477 fprintf(stderr, "%s: ", prog);
481 perror("Internal error");
484 fprintf(stderr, "not an ATM device\n");
487 perror("ioctl (AIOCINFO)");
492 ip_info_base = ip_info =
493 (struct air_ip_vcc_rsp *) air.air_buf_addr;
496 * Sort the information
498 qsort((void *) ip_info,
499 ip_info_len / sizeof(struct air_ip_vcc_rsp),
500 sizeof(struct air_ip_vcc_rsp),
504 * Print the relevant information
506 while (ip_info_len>0) {
507 if (!if_name || !strcmp(if_name, ip_info->aip_intf)) {
508 print_ip_vcc_info(ip_info);
511 ip_info_len -= sizeof(struct air_ip_vcc_rsp);
515 * Release the information from the kernel
517 UM_FREE(ip_info_base);
523 * Process show network interface command
526 * atm show netif [<netif>]
529 * argc number of remaining arguments to command
530 * argv pointer to remaining argument strings
531 * cmdp pointer to command description
538 show_netif(argc, argv, cmdp)
543 int buf_len = sizeof(struct air_netif_rsp) * 3;
544 struct atminfreq air;
545 struct air_netif_rsp *int_info, *int_info_base;
548 * Validate network interface name
550 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
552 if (strlen(argv[0]) > IFNAMSIZ - 1) {
553 fprintf(stderr, "%s: Illegal interface name\n", prog);
556 strcpy(air.air_int_intf, argv[0]);
561 * Get network interface information from the kernel
563 air.air_opcode = AIOCS_INF_NIF;
564 buf_len = do_info_ioctl(&air, buf_len);
566 fprintf(stderr, "%s: ", prog);
570 perror("Internal error");
573 fprintf(stderr, "%s is not an ATM device\n",
577 perror("ioctl (AIOCINFO)");
584 * Print the network interface information
586 int_info_base = int_info =
587 (struct air_netif_rsp *) air.air_buf_addr;
588 for (; buf_len >= sizeof(struct air_netif_rsp); int_info++,
589 buf_len -= sizeof(struct air_netif_rsp)) {
590 print_netif_info(int_info);
592 UM_FREE(int_info_base);
597 * Process interface statistics command
600 * atm show stats interface [<interface-name>]
603 * argc number of remaining arguments to command
604 * argv pointer to remaining argument strings
605 * cmdp pointer to command description
612 show_intf_stats(argc, argv, cmdp)
619 struct atminfreq air;
620 struct air_phy_stat_rsp *pstat_info, *pstat_info_base;
621 struct air_cfg_rsp *cfg_info;
624 * Validate interface name
626 UM_ZERO(intf, sizeof(intf));
628 if (strlen(argv[0]) > IFNAMSIZ - 1) {
629 fprintf(stderr, "%s: Illegal interface name\n",
633 strcpy(intf, argv[0]);
638 * If there are parameters remaining, the request is for
639 * vendor-specific adaptor statistics
643 * Get adapter configuration information
645 buf_len = sizeof(struct air_cfg_rsp);
646 air.air_opcode = AIOCS_INF_CFG;
647 strcpy(air.air_cfg_intf, intf);
648 buf_len = do_info_ioctl(&air, buf_len);
650 fprintf(stderr, "%s: ", prog);
654 perror("Internal error");
657 fprintf(stderr, "%s is not an ATM device\n",
661 perror("ioctl (AIOCINFO)");
666 cfg_info = (struct air_cfg_rsp *)air.air_buf_addr;
669 * Call the appropriate vendor-specific routine
671 switch(cfg_info->acp_vendor) {
673 show_fore200_stats(intf, argc, argv);
676 show_eni_stats(intf, argc, argv);
679 fprintf(stderr, "%s: Unknown adapter vendor\n",
687 * Get generic interface statistics
689 buf_len = sizeof(struct air_phy_stat_rsp) * 3;
690 air.air_opcode = AIOCS_INF_PIS;
691 strcpy(air.air_physt_intf, intf);
692 buf_len = do_info_ioctl(&air, buf_len);
694 fprintf(stderr, "%s: ", prog);
698 perror("Internal error");
701 fprintf(stderr, "%s is not an ATM device\n",
705 perror("ioctl (AIOCINFO)");
712 * Display the interface statistics
714 pstat_info_base = pstat_info =
715 (struct air_phy_stat_rsp *)air.air_buf_addr;
716 for (; buf_len >= sizeof(struct air_phy_stat_rsp);
718 buf_len-=sizeof(struct air_phy_stat_rsp)) {
719 print_intf_stats(pstat_info);
721 UM_FREE((caddr_t)pstat_info_base);
727 * Process VCC statistics command
730 * atm show stats VCC [<interface-name> [<vpi> [<vci>]]]
733 * argc number of remaining arguments to command
734 * argv pointer to remaining argument strings
735 * cmdp pointer to command description
742 show_vcc_stats(argc, argv, cmdp)
748 int vpi = -1, vci = -1;
749 char *cp, *intf = NULL;
750 struct air_vcc_rsp *vcc_info, *vcc_info_base;
753 * Validate interface name
756 if (strlen(argv[0]) > IFNAMSIZ - 1) {
757 fprintf(stderr, "%s: Illegal interface name\n",
769 vpi = strtol(argv[0], &cp, 0);
770 if ((*cp != '\0') || (vpi < 0) || (vpi >= 1 << 8)) {
771 fprintf(stderr, "%s: Invalid VPI value\n", prog);
781 vci = strtol(argv[0], &cp, 0);
782 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
783 fprintf(stderr, "%s: Invalid VCI value\n",
791 * Get VCC information
793 vcc_info_len = get_vcc_info(intf, &vcc_info);
794 if (vcc_info_len == 0)
796 else if (vcc_info_len < 0) {
797 fprintf(stderr, "%s: ", prog);
801 perror("Internal error");
804 fprintf(stderr, "Not an ATM device\n");
807 perror("ioctl (AIOCINFO)");
814 * Sort the VCC information
816 qsort((void *) vcc_info,
817 vcc_info_len / sizeof(struct air_vcc_rsp),
818 sizeof(struct air_vcc_rsp),
822 * Display the VCC statistics
824 vcc_info_base = vcc_info;
825 for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
826 vcc_info_len-=sizeof(struct air_vcc_rsp),
828 if (vpi != -1 && vcc_info->avp_vpi != vpi)
830 if (vci != -1 && vcc_info->avp_vci != vci)
832 print_vcc_stats(vcc_info);
834 UM_FREE(vcc_info_base);
839 * Process VCC information command
842 * atm show VCC [<interface-name> [<vpi> [<vci>] | PVC | SVC]]
845 * argc number of remaining arguments to command
846 * argv pointer to remaining argument strings
847 * cmdp pointer to command description
854 show_vcc(argc, argv, cmdp)
860 int vpi = -1, vci = -1, show_pvc = 0, show_svc = 0;
861 char *cp, *intf = NULL;
862 struct air_vcc_rsp *vcc_info, *vcc_info_base;
865 * Validate interface name
868 if (strlen(argv[0]) > IFNAMSIZ - 1) {
869 fprintf(stderr, "%s: Illegal interface name\n",
881 if (strcasecmp(argv[0], "pvc"))
883 else if (strcasecmp(argv[0], "svc"))
886 vpi = strtol(argv[0], &cp, 0);
887 if ((*cp != '\0') || (vpi < 0) ||
889 fprintf(stderr, "%s: Invalid VPI value\n", prog);
900 vci = strtol(argv[0], &cp, 0);
901 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
902 fprintf(stderr, "%s: Invalid VCI value\n",
910 * Get VCC information
912 vcc_info_len = get_vcc_info(intf, &vcc_info);
913 if (vcc_info_len == 0)
915 else if (vcc_info_len < 0) {
916 fprintf(stderr, "%s: ", prog);
920 perror("Internal error");
923 fprintf(stderr, "Not an ATM device\n");
926 perror("ioctl (AIOCINFO)");
933 * Sort the VCC information
935 qsort((void *) vcc_info,
936 vcc_info_len/sizeof(struct air_vcc_rsp),
937 sizeof(struct air_vcc_rsp),
941 * Display the VCC information
943 vcc_info_base = vcc_info;
944 for (; vcc_info_len >= sizeof(struct air_vcc_rsp);
945 vcc_info_len-=sizeof(struct air_vcc_rsp),
947 if (vpi != -1 && vcc_info->avp_vpi != vpi)
949 if (vci != -1 && vcc_info->avp_vci != vci)
951 if (show_pvc && vcc_info->avp_type & VCC_PVC)
953 if (show_svc && vcc_info->avp_type & VCC_SVC)
955 print_vcc_info(vcc_info);
957 UM_FREE(vcc_info_base);
962 * Process version command
968 * argc number of remaining arguments to command
969 * argv pointer to remaining argument strings
970 * cmdp pointer to command description
977 show_version(argc, argv, cmdp)
982 int buf_len = sizeof(struct air_version_rsp);
983 struct atminfreq air;
984 struct air_version_rsp *ver_info, *ver_info_base;
987 * Get network interface information from the kernel
989 air.air_opcode = AIOCS_INF_VER;
990 buf_len = do_info_ioctl(&air, buf_len);
992 fprintf(stderr, "%s: ", prog);
996 perror("Internal error");
999 fprintf(stderr, "Not an ATM device\n");
1002 perror("ioctl (AIOCINFO)");
1009 * Print the network interface information
1011 ver_info_base = ver_info =
1012 (struct air_version_rsp *) air.air_buf_addr;
1013 for (; buf_len >= sizeof(struct air_version_rsp); ver_info++,
1014 buf_len -= sizeof(struct air_version_rsp)) {
1015 print_version_info(ver_info);
1017 UM_FREE(ver_info_base);
1022 * Comparison function for qsort
1025 * p1 pointer to the first VCC response
1026 * p2 pointer to the second VCC response
1029 * int a number less than, greater than, or equal to zero,
1030 * depending on whether *p1 is less than, greater than, or
1036 const void *p1, *p2;
1039 struct air_vcc_rsp *c1, *c2;
1041 c1 = (struct air_vcc_rsp *) p1;
1042 c2 = (struct air_vcc_rsp *) p2;
1045 * Compare the interface names
1047 rc = strcmp(c1->avp_intf, c2->avp_intf);
1052 * Compare the VPI values
1054 rc = c1->avp_vpi - c2->avp_vpi;
1059 * Compare the VCI values
1061 rc = c1->avp_vci - c2->avp_vci;
1068 rc = c1->avp_type - c2->avp_type;
1074 * Comparison function for qsort
1077 * p1 pointer to the first VCC response
1078 * p2 pointer to the second VCC response
1081 * int a number less than, greater than, or equal to zero,
1082 * depending on whether *p1 is less than, greater than, or
1087 ip_vcc_compare(p1, p2)
1088 const void *p1, *p2;
1091 struct air_ip_vcc_rsp *c1, *c2;
1093 c1 = (struct air_ip_vcc_rsp *) p1;
1094 c2 = (struct air_ip_vcc_rsp *) p2;
1097 * Compare the interface names
1099 rc = strcmp(c1->aip_intf, c2->aip_intf);
1104 * Compare the VPI values
1106 rc = c1->aip_vpi - c2->aip_vpi;
1111 * Compare the VCI values
1113 rc = c1->aip_vci - c2->aip_vci;
1119 * Comparison function for qsort
1122 * p1 pointer to the first ARP or IP map entry
1123 * p2 pointer to the second ARP or IP map entry
1126 * int a number less than, greater than, or equal to zero,
1127 * depending on whether *p1 is less than, greater than, or
1133 const void *p1, *p2;
1136 struct air_arp_rsp *c1, *c2;
1137 struct sockaddr_in *sin1, *sin2;
1139 c1 = (struct air_arp_rsp *) p1;
1140 c2 = (struct air_arp_rsp *) p2;
1141 sin1 = (struct sockaddr_in *) &c1->aap_arp_addr;
1142 sin2 = (struct sockaddr_in *) &c2->aap_arp_addr;
1145 * Compare the IP addresses
1147 if ((rc = sin1->sin_family - sin2->sin_family) != 0)
1149 if ((rc = sin1->sin_addr.s_addr - sin2->sin_addr.s_addr) != 0)
1153 * Compare the ATM addresses
1155 if ((rc = c1->aap_addr.address_format - c2->aap_addr.address_format) != 0)
1157 if ((rc = c1->aap_addr.address_length - c2->aap_addr.address_length) != 0)
1159 switch(c1->aap_addr.address_format) {
1163 case T_ATM_ENDSYS_ADDR:
1164 rc = bcmp((caddr_t)c1->aap_addr.address,
1165 (caddr_t)c2->aap_addr.address,
1166 sizeof(Atm_addr_nsap));
1168 case T_ATM_E164_ADDR:
1169 rc = bcmp((caddr_t)c1->aap_addr.address,
1170 (caddr_t)c2->aap_addr.address,
1171 sizeof(Atm_addr_e164));
1173 case T_ATM_SPANS_ADDR:
1174 rc = bcmp((caddr_t)c1->aap_addr.address,
1175 (caddr_t)c2->aap_addr.address,
1176 sizeof(Atm_addr_spans));