add tools/chkmoddeps
[dragonfly.git] / sbin / atm / atm / atm_show.c
blobc183649efb8fadbeddd2597b3335387bbaa4d19b
1 /*
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.5 2006/10/16 00:15:35 pavalos Exp $
31 * User configuration and display program
32 * --------------------------------------
34 * Routines for "show" subcommand
38 #include <sys/param.h>
39 #include <sys/socket.h>
40 #include <net/if.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>
50 #include <errno.h>
51 #include <libatm.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
56 #include "atm.h"
59 * Local functions
61 static int vcc_compare(const void *, const void *);
62 static int ip_vcc_compare(const void *, const void *);
63 static int arp_compare(const void *, const void *);
67 * Process show ARP command
69 * Command format:
70 * atm show ARP [<ip-addr>]
72 * Arguments:
73 * argc number of remaining arguments to command
74 * argv pointer to remaining argument strings
75 * cmdp pointer to command description
77 * Returns:
78 * none
81 void
82 show_arp(int argc, char **argv, __unused const struct cmd *cmdp)
84 int buf_len, arp_info_len;
85 struct atminfreq air;
86 struct air_arp_rsp *arp_info, *arp_info_base;
87 struct sockaddr_in *sin;
88 union {
89 struct sockaddr_in sin;
90 struct sockaddr sa;
91 } host_addr;
94 * Get IP address of specified host name
96 UM_ZERO(&host_addr, sizeof(host_addr));
97 host_addr.sa.sa_family = AF_INET;
98 if (argc) {
99 sin = get_ip_addr(argv[0]);
100 if (!sin) {
101 fprintf(stderr, "%s: host \'%s\' not found\n",
102 prog, argv[0]);
103 exit(1);
105 host_addr.sin.sin_addr.s_addr = sin->sin_addr.s_addr;
106 } else {
107 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
111 * Get ARP information from the kernel
113 UM_ZERO(&air, sizeof(air));
114 buf_len = sizeof(struct air_arp_rsp) * 10;
115 air.air_opcode = AIOCS_INF_ARP;
116 air.air_arp_addr = host_addr.sa;
117 arp_info_len = do_info_ioctl(&air, buf_len);
118 if (arp_info_len < 0) {
119 fprintf(stderr, "%s: ", prog);
120 switch (errno) {
121 case ENOPROTOOPT:
122 case EOPNOTSUPP:
123 perror("Internal error");
124 break;
125 case ENXIO:
126 fprintf(stderr, "not an ATM device\n");
127 break;
128 default:
129 perror("ioctl (AIOCINFO)");
130 break;
132 exit(1);
134 arp_info_base = arp_info =
135 (struct air_arp_rsp *) air.air_buf_addr;
138 * Sort the ARP table
140 qsort((void *) arp_info,
141 arp_info_len / sizeof(struct air_arp_rsp),
142 sizeof(struct air_arp_rsp),
143 arp_compare);
146 * Print the relevant information
148 while (arp_info_len > 0) {
149 print_arp_info(arp_info);
150 arp_info++;
151 arp_info_len -= sizeof(struct air_arp_rsp);
155 * Release the information from the kernel
157 UM_FREE(arp_info_base);
162 * Process show ATM ARP server command
164 * Command format:
165 * atm show arpserver [<interface-name>]
167 * Arguments:
168 * argc number of remaining arguments to command
169 * argv pointer to remaining argument strings
170 * cmdp pointer to command description
172 * Returns:
173 * none
176 void
177 show_arpserv(int argc, char **argv, __unused const struct cmd *cmdp)
179 int asrv_info_len, buf_len = sizeof(struct air_asrv_rsp) * 3;
180 struct atminfreq air;
181 struct air_asrv_rsp *asrv_info, *asrv_info_base;
184 * Validate interface name
186 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
187 if (argc) {
188 if (strlen(argv[0]) > IFNAMSIZ - 1) {
189 fprintf(stderr, "%s: Illegal interface name\n",
190 prog);
191 exit(1);
193 strcpy(air.air_int_intf, argv[0]);
194 argc--; argv++;
198 * Get interface information from the kernel
200 air.air_opcode = AIOCS_INF_ASV;
201 buf_len = do_info_ioctl(&air, buf_len);
202 if (buf_len < 0) {
203 fprintf(stderr, "%s: ", prog);
204 switch (errno) {
205 case ENOPROTOOPT:
206 case EOPNOTSUPP:
207 perror("Internal error");
208 break;
209 case ENXIO:
210 fprintf(stderr, "%s is not an ATM device\n",
211 argv[0]);
212 break;
213 default:
214 perror("ioctl (AIOCINFO)");
215 break;
217 exit(1);
221 * Print the interface information
223 asrv_info_base = asrv_info =
224 (struct air_asrv_rsp *) air.air_buf_addr;
225 for (; (size_t)buf_len >= sizeof(struct air_asrv_rsp);
226 asrv_info = (struct air_asrv_rsp *)
227 ((u_long)asrv_info + asrv_info_len),
228 buf_len -= asrv_info_len) {
229 print_asrv_info(asrv_info);
230 asrv_info_len = sizeof(struct air_asrv_rsp) +
231 asrv_info->asp_nprefix *
232 sizeof(struct in_addr) * 2;
234 UM_FREE(asrv_info_base);
239 * Process show ATM adapter configuration command
241 * Command format:
242 * atm show config [<interface-name>]
244 * Arguments:
245 * argc number of remaining arguments to command
246 * argv pointer to remaining argument strings
247 * cmdp pointer to command description
249 * Returns:
250 * none
253 void
254 show_config(int argc, char **argv, __unused const struct cmd *cmdp)
256 int buf_len = sizeof(struct air_asrv_rsp) * 3;
257 struct atminfreq air;
258 struct air_cfg_rsp *cfg_info, *cfg_info_base;
261 * Validate interface name
263 UM_ZERO(air.air_cfg_intf, sizeof(air.air_cfg_intf));
264 if (argc) {
265 if (strlen(argv[0]) > IFNAMSIZ - 1) {
266 fprintf(stderr, "%s: Illegal interface name\n",
267 prog);
268 exit(1);
270 strcpy(air.air_cfg_intf, argv[0]);
271 argc--; argv++;
275 * Get configuration information from the kernel
277 air.air_opcode = AIOCS_INF_CFG;
278 buf_len = do_info_ioctl(&air, buf_len);
279 if (buf_len < 0) {
280 fprintf(stderr, "%s: ", prog);
281 switch (errno) {
282 case ENOPROTOOPT:
283 case EOPNOTSUPP:
284 perror("Internal error");
285 break;
286 case ENXIO:
287 fprintf(stderr, "%s is not an ATM device\n",
288 argv[0]);
289 break;
290 default:
291 perror("ioctl (AIOCINFO)");
292 break;
294 exit(1);
298 * Print the interface information
300 cfg_info_base = cfg_info =
301 (struct air_cfg_rsp *) air.air_buf_addr;
302 for (; (size_t)buf_len >= sizeof(struct air_cfg_rsp); cfg_info++,
303 buf_len -= sizeof(struct air_cfg_rsp)) {
304 print_cfg_info(cfg_info);
306 UM_FREE(cfg_info_base);
311 * Process show interface command
313 * Command format:
314 * atm show interface [<interface-name>]
316 * Arguments:
317 * argc number of remaining arguments to command
318 * argv pointer to remaining argument strings
319 * cmdp pointer to command description
321 * Returns:
322 * none
325 void
326 show_intf(int argc, char **argv, __unused const struct cmd *cmdp)
328 int buf_len = sizeof(struct air_int_rsp) * 3;
329 struct atminfreq air;
330 struct air_int_rsp *int_info, *int_info_base;
333 * Validate interface name
335 UM_ZERO(&air, sizeof(air));
336 if (argc) {
337 if (strlen(argv[0]) > IFNAMSIZ - 1) {
338 fprintf(stderr, "%s: Illegal interface name\n",
339 prog);
340 exit(1);
342 strcpy(air.air_int_intf, argv[0]);
343 argc--; argv++;
347 * Get interface information from the kernel
349 air.air_opcode = AIOCS_INF_INT;
350 buf_len = do_info_ioctl(&air, buf_len);
351 if (buf_len < 0) {
352 fprintf(stderr, "%s: ", prog);
353 switch (errno) {
354 case ENOPROTOOPT:
355 case EOPNOTSUPP:
356 perror("Internal error");
357 break;
358 case ENXIO:
359 fprintf(stderr, "%s is not an ATM device\n",
360 argv[0]);
361 break;
362 default:
363 perror("ioctl (AIOCINFO)");
364 break;
366 exit(1);
370 * Print the interface information
372 int_info_base = int_info =
373 (struct air_int_rsp *) air.air_buf_addr;
374 for (; (size_t)buf_len >= sizeof(struct air_int_rsp); int_info++,
375 buf_len -= sizeof(struct air_int_rsp)) {
376 print_intf_info(int_info);
378 UM_FREE(int_info_base);
383 * Process show IP VCCs command
385 * Command format:
386 * atm show ipvcc [<ip-addr>]
388 * Arguments:
389 * argc number of remaining arguments to command
390 * argv pointer to remaining argument strings
391 * cmdp pointer to command description
393 * Returns:
394 * none
397 void
398 show_ip_vcc(int argc, char **argv, __unused const struct cmd *cmdp)
400 int buf_len, ip_info_len, rc;
401 char *if_name = NULL;
402 struct atminfreq air;
403 struct air_ip_vcc_rsp *ip_info, *ip_info_base;
404 struct sockaddr_in *sin;
405 union {
406 struct sockaddr_in sin;
407 struct sockaddr sa;
408 } host_addr;
411 * First parameter can be a netif name, an IP host name, or
412 * an IP address. Figure out which it is.
414 UM_ZERO(&host_addr, sizeof(host_addr));
415 host_addr.sa.sa_family = AF_INET;
416 if (argc) {
417 rc = verify_nif_name(argv[0]);
418 if (rc < 0) {
420 * Error occured
422 fprintf(stderr, "%s: ", prog);
423 switch (errno) {
424 case ENOPROTOOPT:
425 case EOPNOTSUPP:
426 perror("Internal error");
427 break;
428 case ENXIO:
429 fprintf(stderr, "%s is not an ATM device\n",
430 argv[0]);
431 break;
432 default:
433 perror("ioctl (AIOCINFO)");
434 break;
436 exit(1);
437 } else if (rc > 0) {
439 * Parameter is a valid netif name
441 if_name = argv[0];
442 } else {
444 * Get IP address of specified host name
446 sin = get_ip_addr(argv[0]);
447 host_addr.sin.sin_addr.s_addr =
448 sin->sin_addr.s_addr;
450 } else {
451 host_addr.sin.sin_addr.s_addr = INADDR_ANY;
455 * Get IP map information from the kernel
457 buf_len = sizeof(struct air_ip_vcc_rsp) * 10;
458 air.air_opcode = AIOCS_INF_IPM;
459 air.air_ip_addr = host_addr.sa;
460 ip_info_len = do_info_ioctl(&air, buf_len);
461 if (ip_info_len < 0) {
462 fprintf(stderr, "%s: ", prog);
463 switch (errno) {
464 case ENOPROTOOPT:
465 case EOPNOTSUPP:
466 perror("Internal error");
467 break;
468 case ENXIO:
469 fprintf(stderr, "not an ATM device\n");
470 break;
471 default:
472 perror("ioctl (AIOCINFO)");
473 break;
475 exit(1);
477 ip_info_base = ip_info =
478 (struct air_ip_vcc_rsp *) air.air_buf_addr;
481 * Sort the information
483 qsort((void *) ip_info,
484 ip_info_len / sizeof(struct air_ip_vcc_rsp),
485 sizeof(struct air_ip_vcc_rsp),
486 ip_vcc_compare);
489 * Print the relevant information
491 while (ip_info_len>0) {
492 if (!if_name || !strcmp(if_name, ip_info->aip_intf)) {
493 print_ip_vcc_info(ip_info);
495 ip_info++;
496 ip_info_len -= sizeof(struct air_ip_vcc_rsp);
500 * Release the information from the kernel
502 UM_FREE(ip_info_base);
508 * Process show network interface command
510 * Command format:
511 * atm show netif [<netif>]
513 * Arguments:
514 * argc number of remaining arguments to command
515 * argv pointer to remaining argument strings
516 * cmdp pointer to command description
518 * Returns:
519 * none
522 void
523 show_netif(int argc, char **argv, __unused const struct cmd *cmdp)
525 int buf_len = sizeof(struct air_netif_rsp) * 3;
526 struct atminfreq air;
527 struct air_netif_rsp *int_info, *int_info_base;
530 * Validate network interface name
532 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
533 if (argc) {
534 if (strlen(argv[0]) > IFNAMSIZ - 1) {
535 fprintf(stderr, "%s: Illegal interface name\n", prog);
536 exit(1);
538 strcpy(air.air_int_intf, argv[0]);
539 argc--; argv++;
543 * Get network interface information from the kernel
545 air.air_opcode = AIOCS_INF_NIF;
546 buf_len = do_info_ioctl(&air, buf_len);
547 if (buf_len < 0) {
548 fprintf(stderr, "%s: ", prog);
549 switch (errno) {
550 case ENOPROTOOPT:
551 case EOPNOTSUPP:
552 perror("Internal error");
553 break;
554 case ENXIO:
555 fprintf(stderr, "%s is not an ATM device\n",
556 argv[0]);
557 break;
558 default:
559 perror("ioctl (AIOCINFO)");
560 break;
562 exit(1);
566 * Print the network interface information
568 int_info_base = int_info =
569 (struct air_netif_rsp *) air.air_buf_addr;
570 for (; (size_t)buf_len >= sizeof(struct air_netif_rsp); int_info++,
571 buf_len -= sizeof(struct air_netif_rsp)) {
572 print_netif_info(int_info);
574 UM_FREE(int_info_base);
579 * Process interface statistics command
581 * Command format:
582 * atm show stats interface [<interface-name>]
584 * Arguments:
585 * argc number of remaining arguments to command
586 * argv pointer to remaining argument strings
587 * cmdp pointer to command description
589 * Returns:
590 * none
593 void
594 show_intf_stats(int argc, char **argv, __unused const struct cmd *cmdp)
596 int buf_len;
597 char intf[IFNAMSIZ];
598 struct atminfreq air;
599 struct air_phy_stat_rsp *pstat_info, *pstat_info_base;
600 struct air_cfg_rsp *cfg_info;
603 * Validate interface name
605 UM_ZERO(intf, sizeof(intf));
606 if (argc) {
607 if (strlen(argv[0]) > IFNAMSIZ - 1) {
608 fprintf(stderr, "%s: Illegal interface name\n",
609 prog);
610 exit(1);
612 strcpy(intf, argv[0]);
613 argc--; argv++;
617 * If there are parameters remaining, the request is for
618 * vendor-specific adaptor statistics
620 if (argc) {
622 * Get adapter configuration information
624 buf_len = sizeof(struct air_cfg_rsp);
625 air.air_opcode = AIOCS_INF_CFG;
626 strcpy(air.air_cfg_intf, intf);
627 buf_len = do_info_ioctl(&air, buf_len);
628 if (buf_len < 0) {
629 fprintf(stderr, "%s: ", prog);
630 switch (errno) {
631 case ENOPROTOOPT:
632 case EOPNOTSUPP:
633 perror("Internal error");
634 break;
635 case ENXIO:
636 fprintf(stderr, "%s is not an ATM device\n",
637 intf);
638 break;
639 default:
640 perror("ioctl (AIOCINFO)");
641 break;
643 exit(1);
645 cfg_info = (struct air_cfg_rsp *)air.air_buf_addr;
648 * Call the appropriate vendor-specific routine
650 switch(cfg_info->acp_vendor) {
651 case VENDOR_FORE:
652 show_fore200_stats(intf, argc, argv);
653 break;
654 case VENDOR_ENI:
655 show_eni_stats(intf, argc, argv);
656 break;
657 default:
658 fprintf(stderr, "%s: Unknown adapter vendor\n",
659 prog);
660 break;
663 UM_FREE(cfg_info);
664 } else {
666 * Get generic interface statistics
668 buf_len = sizeof(struct air_phy_stat_rsp) * 3;
669 air.air_opcode = AIOCS_INF_PIS;
670 strcpy(air.air_physt_intf, intf);
671 buf_len = do_info_ioctl(&air, buf_len);
672 if (buf_len < 0) {
673 fprintf(stderr, "%s: ", prog);
674 switch (errno) {
675 case ENOPROTOOPT:
676 case EOPNOTSUPP:
677 perror("Internal error");
678 break;
679 case ENXIO:
680 fprintf(stderr, "%s is not an ATM device\n",
681 intf);
682 break;
683 default:
684 perror("ioctl (AIOCINFO)");
685 break;
687 exit(1);
691 * Display the interface statistics
693 pstat_info_base = pstat_info =
694 (struct air_phy_stat_rsp *)air.air_buf_addr;
695 for (; (size_t)buf_len >= sizeof(struct air_phy_stat_rsp);
696 pstat_info++,
697 buf_len-=sizeof(struct air_phy_stat_rsp)) {
698 print_intf_stats(pstat_info);
700 UM_FREE((caddr_t)pstat_info_base);
706 * Process VCC statistics command
708 * Command format:
709 * atm show stats VCC [<interface-name> [<vpi> [<vci>]]]
711 * Arguments:
712 * argc number of remaining arguments to command
713 * argv pointer to remaining argument strings
714 * cmdp pointer to command description
716 * Returns:
717 * none
720 void
721 show_vcc_stats(int argc, char **argv, __unused const struct cmd *cmdp)
723 int vcc_info_len;
724 int vpi = -1, vci = -1;
725 char *cp, *intf = NULL;
726 struct air_vcc_rsp *vcc_info, *vcc_info_base;
729 * Validate interface name
731 if (argc) {
732 if (strlen(argv[0]) > IFNAMSIZ - 1) {
733 fprintf(stderr, "%s: Illegal interface name\n",
734 prog);
735 exit(1);
737 intf = argv[0];
738 argc--; argv++;
742 * Validate VPI value
744 if (argc) {
745 vpi = strtol(argv[0], &cp, 0);
746 if ((*cp != '\0') || (vpi < 0) || (vpi >= 1 << 8)) {
747 fprintf(stderr, "%s: Invalid VPI value\n", prog);
748 exit(1);
750 argc--; argv++;
754 * Validate VCI value
756 if (argc) {
757 vci = strtol(argv[0], &cp, 0);
758 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
759 fprintf(stderr, "%s: Invalid VCI value\n",
760 prog);
761 exit(1);
763 argc--; argv++;
767 * Get VCC information
769 vcc_info_len = get_vcc_info(intf, &vcc_info);
770 if (vcc_info_len == 0)
771 exit(1);
772 else if (vcc_info_len < 0) {
773 fprintf(stderr, "%s: ", prog);
774 switch (errno) {
775 case ENOPROTOOPT:
776 case EOPNOTSUPP:
777 perror("Internal error");
778 break;
779 case ENXIO:
780 fprintf(stderr, "Not an ATM device\n");
781 break;
782 default:
783 perror("ioctl (AIOCINFO)");
784 break;
786 exit(1);
790 * Sort the VCC information
792 qsort((void *) vcc_info,
793 vcc_info_len / sizeof(struct air_vcc_rsp),
794 sizeof(struct air_vcc_rsp),
795 vcc_compare);
798 * Display the VCC statistics
800 vcc_info_base = vcc_info;
801 for (; (size_t)vcc_info_len >= sizeof(struct air_vcc_rsp);
802 vcc_info_len-=sizeof(struct air_vcc_rsp),
803 vcc_info++) {
804 if (vpi != -1 && vcc_info->avp_vpi != vpi)
805 continue;
806 if (vci != -1 && vcc_info->avp_vci != vci)
807 continue;
808 print_vcc_stats(vcc_info);
810 UM_FREE(vcc_info_base);
815 * Process VCC information command
817 * Command format:
818 * atm show VCC [<interface-name> [<vpi> [<vci>] | PVC | SVC]]
820 * Arguments:
821 * argc number of remaining arguments to command
822 * argv pointer to remaining argument strings
823 * cmdp pointer to command description
825 * Returns:
826 * none
829 void
830 show_vcc(int argc, char **argv, __unused const struct cmd *cmdp)
832 int vcc_info_len;
833 int vpi = -1, vci = -1, show_pvc = 0, show_svc = 0;
834 char *cp, *intf = NULL;
835 struct air_vcc_rsp *vcc_info, *vcc_info_base;
838 * Validate interface name
840 if (argc) {
841 if (strlen(argv[0]) > IFNAMSIZ - 1) {
842 fprintf(stderr, "%s: Illegal interface name\n",
843 prog);
844 exit(1);
846 intf = argv[0];
847 argc--; argv++;
851 * Validate VPI value
853 if (argc) {
854 if (strcasecmp(argv[0], "pvc"))
855 show_pvc = 1;
856 else if (strcasecmp(argv[0], "svc"))
857 show_svc = 1;
858 else {
859 vpi = strtol(argv[0], &cp, 0);
860 if ((*cp != '\0') || (vpi < 0) ||
861 (vpi >= 1 << 8)) {
862 fprintf(stderr, "%s: Invalid VPI value\n", prog);
863 exit(1);
866 argc--; argv++;
870 * Validate VCI value
872 if (argc) {
873 vci = strtol(argv[0], &cp, 0);
874 if ((*cp != '\0') || (vci <= 0) || (vci >= 1 << 16)) {
875 fprintf(stderr, "%s: Invalid VCI value\n",
876 prog);
877 exit(1);
879 argc--; argv++;
883 * Get VCC information
885 vcc_info_len = get_vcc_info(intf, &vcc_info);
886 if (vcc_info_len == 0)
887 exit(1);
888 else if (vcc_info_len < 0) {
889 fprintf(stderr, "%s: ", prog);
890 switch (errno) {
891 case ENOPROTOOPT:
892 case EOPNOTSUPP:
893 perror("Internal error");
894 break;
895 case ENXIO:
896 fprintf(stderr, "Not an ATM device\n");
897 break;
898 default:
899 perror("ioctl (AIOCINFO)");
900 break;
902 exit(1);
906 * Sort the VCC information
908 qsort((void *) vcc_info,
909 vcc_info_len/sizeof(struct air_vcc_rsp),
910 sizeof(struct air_vcc_rsp),
911 vcc_compare);
914 * Display the VCC information
916 vcc_info_base = vcc_info;
917 for (; (size_t)vcc_info_len >= sizeof(struct air_vcc_rsp);
918 vcc_info_len-=sizeof(struct air_vcc_rsp),
919 vcc_info++) {
920 if (vpi != -1 && vcc_info->avp_vpi != vpi)
921 continue;
922 if (vci != -1 && vcc_info->avp_vci != vci)
923 continue;
924 if (show_pvc && vcc_info->avp_type & VCC_PVC)
925 continue;
926 if (show_svc && vcc_info->avp_type & VCC_SVC)
927 continue;
928 print_vcc_info(vcc_info);
930 UM_FREE(vcc_info_base);
935 * Process version command
937 * Command format:
938 * atm show version
940 * Arguments:
941 * argc number of remaining arguments to command
942 * argv pointer to remaining argument strings
943 * cmdp pointer to command description
945 * Returns:
946 * none
949 void
950 show_version(__unused int argc, __unused char **argv,
951 __unused const struct cmd *cmdp)
953 int buf_len = sizeof(struct air_version_rsp);
954 struct atminfreq air;
955 struct air_version_rsp *ver_info, *ver_info_base;
958 * Get network interface information from the kernel
960 air.air_opcode = AIOCS_INF_VER;
961 buf_len = do_info_ioctl(&air, buf_len);
962 if (buf_len < 0) {
963 fprintf(stderr, "%s: ", prog);
964 switch (errno) {
965 case ENOPROTOOPT:
966 case EOPNOTSUPP:
967 perror("Internal error");
968 break;
969 case ENXIO:
970 fprintf(stderr, "Not an ATM device\n");
971 break;
972 default:
973 perror("ioctl (AIOCINFO)");
974 break;
976 exit(1);
980 * Print the network interface information
982 ver_info_base = ver_info =
983 (struct air_version_rsp *) air.air_buf_addr;
984 for (; (size_t)buf_len >= sizeof(struct air_version_rsp); ver_info++,
985 buf_len -= sizeof(struct air_version_rsp)) {
986 print_version_info(ver_info);
988 UM_FREE(ver_info_base);
993 * Comparison function for qsort
995 * Arguments:
996 * p1 pointer to the first VCC response
997 * p2 pointer to the second VCC response
999 * Returns:
1000 * int a number less than, greater than, or equal to zero,
1001 * depending on whether *p1 is less than, greater than, or
1002 * equal to *p2
1005 static int
1006 vcc_compare(const void *p1, const void *p2)
1008 int rc;
1009 const struct air_vcc_rsp *c1, *c2;
1011 c1 = (const struct air_vcc_rsp *) p1;
1012 c2 = (const struct air_vcc_rsp *) p2;
1015 * Compare the interface names
1017 rc = strcmp(c1->avp_intf, c2->avp_intf);
1018 if (rc)
1019 return(rc);
1022 * Compare the VPI values
1024 rc = c1->avp_vpi - c2->avp_vpi;
1025 if (rc)
1026 return(rc);
1029 * Compare the VCI values
1031 rc = c1->avp_vci - c2->avp_vci;
1032 if (rc)
1033 return(rc);
1036 * Compare the types
1038 rc = c1->avp_type - c2->avp_type;
1039 return(rc);
1044 * Comparison function for qsort
1046 * Arguments:
1047 * p1 pointer to the first VCC response
1048 * p2 pointer to the second VCC response
1050 * Returns:
1051 * int a number less than, greater than, or equal to zero,
1052 * depending on whether *p1 is less than, greater than, or
1053 * equal to *p2
1056 static int
1057 ip_vcc_compare(const void *p1, const void *p2)
1059 int rc;
1060 const struct air_ip_vcc_rsp *c1, *c2;
1062 c1 = (const struct air_ip_vcc_rsp *) p1;
1063 c2 = (const struct air_ip_vcc_rsp *) p2;
1066 * Compare the interface names
1068 rc = strcmp(c1->aip_intf, c2->aip_intf);
1069 if (rc)
1070 return(rc);
1073 * Compare the VPI values
1075 rc = c1->aip_vpi - c2->aip_vpi;
1076 if (rc)
1077 return(rc);
1080 * Compare the VCI values
1082 rc = c1->aip_vci - c2->aip_vci;
1083 return(rc);
1088 * Comparison function for qsort
1090 * Arguments:
1091 * p1 pointer to the first ARP or IP map entry
1092 * p2 pointer to the second ARP or IP map entry
1094 * Returns:
1095 * int a number less than, greater than, or equal to zero,
1096 * depending on whether *p1 is less than, greater than, or
1097 * equal to *p2
1100 static int
1101 arp_compare(const void *p1, const void *p2)
1103 int rc;
1104 const struct air_arp_rsp *c1, *c2;
1105 const struct sockaddr_in *sin1, *sin2;
1107 c1 = (const struct air_arp_rsp *) p1;
1108 c2 = (const struct air_arp_rsp *) p2;
1109 sin1 = (const struct sockaddr_in *) &c1->aap_arp_addr;
1110 sin2 = (const struct sockaddr_in *) &c2->aap_arp_addr;
1113 * Compare the IP addresses
1115 if ((rc = sin1->sin_family - sin2->sin_family) != 0)
1116 return(rc);
1117 if ((rc = sin1->sin_addr.s_addr - sin2->sin_addr.s_addr) != 0)
1118 return(rc);
1121 * Compare the ATM addresses
1123 if ((rc = c1->aap_addr.address_format - c2->aap_addr.address_format) != 0)
1124 return(rc);
1125 if ((rc = c1->aap_addr.address_length - c2->aap_addr.address_length) != 0)
1126 return(rc);
1127 switch(c1->aap_addr.address_format) {
1128 case T_ATM_ABSENT:
1129 rc = 0;
1130 break;
1131 case T_ATM_ENDSYS_ADDR:
1132 rc = bcmp(c1->aap_addr.address,
1133 c2->aap_addr.address,
1134 sizeof(Atm_addr_nsap));
1135 break;
1136 case T_ATM_E164_ADDR:
1137 rc = bcmp(c1->aap_addr.address,
1138 c2->aap_addr.address,
1139 sizeof(Atm_addr_e164));
1140 break;
1141 case T_ATM_SPANS_ADDR:
1142 rc = bcmp(c1->aap_addr.address,
1143 c2->aap_addr.address,
1144 sizeof(Atm_addr_spans));
1145 break;
1148 return(rc);