nlookup.9 - document nlookup_init_root
[dragonfly.git] / sbin / atm / atm / atm.c
blobba907f8c1bd75ec55e8b2500ad8ec2dc4f4a65ae
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.c,v 1.3.2.1 2000/07/01 06:02:14 ps Exp $
27 * @(#) $DragonFly: src/sbin/atm/atm/atm.c,v 1.5 2006/10/16 00:15:35 pavalos Exp $
31 * User configuration and display program
32 * --------------------------------------
34 * Main routine
38 #include <sys/param.h>
39 #include <sys/socket.h>
40 #include <sys/sockio.h>
41 #include <net/if.h>
42 #include <netinet/in.h>
43 #include <netatm/port.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_if.h>
46 #include <netatm/atm_sap.h>
47 #include <netatm/atm_sys.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_sigmgr.h>
50 #include <netatm/atm_ioctl.h>
52 #include <errno.h>
53 #include <libatm.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <unistd.h>
59 #include "atm.h"
62 * Usage string
64 #define USAGE_STR "Interface management subcommands:\n\
65 attach <intf> <protocol>\n\
66 detach <intf>\n\
67 set mac <intf> <MAC/ESI address>\n\
68 set netif <intf> <prefix> <n>\n\
69 set prefix <intf> <NSAP prefix>\n\
70 show config [<intf>]\n\
71 show interface [<intf>]\n\
72 show netif [<netif>]\n\
73 show stats interface [<intf> phy | dev | atm | aal0 | aal4 |\n\
74 aal5 | driver]\n\
75 \n\
76 VC management subcommands:\n\
77 add pvc <intf> <vpi> <vci> <aal> <encaps> <owner> ...\n\
78 delete pvc <intf> <vpi> <vci>\n\
79 delete svc <intf> <vpi> <vci>\n\
80 show stats vcc [<intf> [vpi [vci]]]\n\
81 show vcc [<intf> [<vpi> [<vci>] | SVC | PVC]]\n\
82 \n\
83 IP management subcommands:\n\
84 add arp [<netif>] <IP addr> <ATM addr>\n\
85 add pvc <intf> <vpi> <vci> <aal> <encaps> IP <netif> <IP addr> |\n\
86 dynamic\n\
87 delete arp [<netif>] <IP addr>\n\
88 set arpserver <netif> <server> <IP prefix> ...\n\
89 show arp [<host>]\n\
90 show arpserver [<netif>]\n\
91 show ipvcc [<IP addr> | <netif>]\n\
92 \n\
93 Miscellaneous subcommands:\n\
94 help\n\
95 show version\n"
99 * Local definitions
102 static int do_cmd(const struct cmd *, int, char **);
103 static void usage(const struct cmd *, const char *);
104 static void attach(int, char **, const struct cmd *);
105 static void detach(int, char **, const struct cmd *);
106 static void pvc_add(int, char **, const struct cmd *);
107 static void arp_add(int, char **, const struct cmd *);
108 static void pvc_dlt(int, char **, const struct cmd *);
109 static void svc_dlt(int, char **, const struct cmd *);
110 static void vcc_dlt(int, char **, const struct cmd *, struct atmdelreq *);
111 static void arp_dlt(int, char **, const struct cmd *);
112 static void help(int, char **, const struct cmd *);
114 static const struct cmd add_subcmd[] = {
115 { "arp", 2, 3, arp_add, "[<netif>] <IP addr> <ATM addr>" },
116 { "pvc", 6, 12, pvc_add, "<intf> <vpi> <vci> <aal> <encaps> <owner> ..." },
117 { 0, 0, 0, NULL, "" }
120 static const struct cmd dlt_subcmd[] = {
121 { "arp", 1, 2, arp_dlt, "[<netif>] <IP addr>" },
122 { "pvc", 3, 3, pvc_dlt, "<intf> <vpi> <vci>" },
123 { "svc", 3, 3, svc_dlt, "<intf> <vpi> <vci>" },
124 { 0, 0, 0, NULL, "" }
127 static const struct cmd set_subcmd[] = {
128 { "arpserver", 2, 18, set_arpserver, "<netif> <server>" },
129 { "mac", 2, 2, set_macaddr, "<intf> <MAC/ESI address>" },
130 { "netif", 3, 3, set_netif, "<intf> <prefix> <n>" },
131 { "prefix", 2, 2, set_prefix, "<intf> <NSAP prefix>" },
132 { 0, 0, 0, NULL, ""}
135 static const struct cmd stats_subcmd[] = {
136 { "interface", 0, 2, show_intf_stats, "[<intf> [cfg | phy | dev | atm | aal0 | aal4 | aal5 | driver]]" },
137 { "vcc", 0, 3, show_vcc_stats, "[<intf> [vpi [vci]]]" },
138 { 0, 0, 0, NULL, "" }
141 static const struct cmd show_subcmd[] = {
142 { "arp", 0, 1, show_arp, "[<host>]" },
143 { "arpserver", 0, 1, show_arpserv, "[<netif>]" },
144 { "config", 0, 1, show_config, "[<intf>]" },
145 { "interface", 0, 1, show_intf, "[<intf>]" },
146 { "ipvcc", 0, 3, show_ip_vcc, "[<IP addr> | <netif>]" },
147 { "netif", 0, 1, show_netif, "[<netif>]" },
148 { "stats", 0, 3, NULL, (const char *) stats_subcmd },
149 { "vcc", 0, 3, show_vcc, "[<intf>] [<vpi> [<vci>] | SVC | PVC]" },
150 { "version", 0, 0, show_version, "" },
151 { 0, 0, 0, NULL, "" }
154 static const struct cmd cmds[] = {
155 { "add", 0, 0, NULL, (const char *) add_subcmd },
156 { "attach", 2, 2, attach, "<intf> <protocol>" },
157 { "delete", 0, 0, NULL, (const char *) dlt_subcmd },
158 { "detach", 1, 1, detach, "<intf>" },
159 { "set", 0, 0, NULL, (const char *) set_subcmd },
160 { "show", 0, 0, NULL, (const char *) show_subcmd },
161 { "help", 0, 99, help, "" },
162 { 0, 0, 0, NULL, "" }
167 * Supported signalling protocols
169 static const struct proto protos[] = {
170 { "SIGPVC", ATM_SIG_PVC },
171 { "SPANS", ATM_SIG_SPANS },
172 { "UNI30", ATM_SIG_UNI30 },
173 { "UNI31", ATM_SIG_UNI31 },
174 { "UNI40", ATM_SIG_UNI40 },
175 { 0, 0 }
179 * Supported VCC owners
181 static const struct owner owners[] = {
182 { "IP", ENDPT_IP, ip_pvcadd },
183 { "SPANS", ENDPT_SPANS_SIG,0 },
184 { "SPANS CLS", ENDPT_SPANS_CLS,0 },
185 { "UNI SIG", ENDPT_UNI_SIG, 0 },
186 { 0, 0, 0 }
190 * Supported AAL parameters
192 const struct aal aals[] = {
193 { "Null", ATM_AAL0 },
194 { "AAL0", ATM_AAL0 },
195 { "AAL1", ATM_AAL1 },
196 { "AAL2", ATM_AAL2 },
197 { "AAL4", ATM_AAL3_4 },
198 { "AAL3", ATM_AAL3_4 },
199 { "AAL3/4", ATM_AAL3_4 },
200 { "AAL5", ATM_AAL5 },
201 { 0, 0 },
205 * Supported VCC encapsulations
207 const struct encaps encaps[] = {
208 { "Null", ATM_ENC_NULL },
209 { "None", ATM_ENC_NULL },
210 { "LLC/SNAP", ATM_ENC_LLC },
211 { "LLC", ATM_ENC_LLC },
212 { "SNAP", ATM_ENC_LLC },
213 { 0, 0 },
217 char *prog;
218 char prefix[128] = "";
222 main(int argc, char **argv)
224 int error;
227 * Save program name, ignoring any path components
229 if ((prog = (char *)strrchr(argv[0], '/')) != NULL)
230 prog++;
231 else
232 prog = argv[0];
234 if (argc < 2) {
235 usage(cmds, "");
236 exit(1);
238 argc--; argv++;
241 * Validate and process command
243 if ((error = do_cmd(cmds, argc, argv)) != 0)
244 usage(cmds, "");
246 exit(error);
251 * Validate and process user command
253 * Arguments:
254 * descp pointer to command description array
255 * argc number of arguments left in command
256 * argv pointer to argument strings
258 * Returns:
259 * none
262 static int
263 do_cmd(const struct cmd *descp, int argc, char **argv)
265 const struct cmd *cmdp = NULL;
268 * Make sure we have paramaters to process
270 if (!argc) {
271 usage(cmds, "");
272 exit(1);
276 * Figure out what command user wants
278 for (; descp->name; descp++) {
280 * Use an exact match if there is one
282 if (!strcasecmp(descp->name, argv[0])) {
283 cmdp = descp;
284 break;
287 * Look for a match on the first part of keyword
289 if (!strncasecmp(descp->name, argv[0], strlen(argv[0]))) {
290 if (cmdp) {
291 fprintf(stderr, "%s: Ambiguous parameter \"%s\"\n",
292 prog, argv[0]);
293 exit(1);
295 cmdp = descp;
298 if (!cmdp)
299 return(1);
300 argc--; argv++;
303 * See if this command has subcommands
305 if (cmdp->func == NULL) {
306 strcat(prefix, cmdp->name);
307 strcat(prefix, " ");
308 return(do_cmd((const struct cmd *)cmdp->help, argc, argv));
312 * Minimal validation
314 if ((argc < cmdp->minp) || (argc > cmdp->maxp)) {
315 fprintf(stderr, "%s: Invalid number of arguments\n",
316 prog);
317 fprintf(stderr, "\tformat is: %s%s %s\n",
318 prefix, cmdp->name, cmdp->help);
319 exit(1);
323 * Process command
325 (*cmdp->func)(argc, argv, cmdp);
326 return(0);
331 * Print command usage information
333 * Arguments:
334 * cmdp pointer to command description
335 * pref pointer current command prefix
337 * Returns:
338 * none
341 static void
342 usage(__unused const struct cmd *cmdp, __unused const char *pref)
344 fprintf(stderr, "usage: %s command [arg] [arg]...\n", prog);
345 fprintf(stderr, USAGE_STR);
350 * Process interface attach command
352 * Command format:
353 * atm attach <interface_name> <protocol_name>
355 * Arguments:
356 * argc number of arguments to command
357 * argv pointer to argument strings
358 * cmdp pointer to command description
360 * Returns:
361 * none
364 static void
365 attach(__unused int argc, char **argv, __unused const struct cmd *cmdp)
367 struct atmcfgreq aar;
368 const struct proto *prp;
369 int s;
372 * Validate interface name
374 if (strlen(argv[0]) > sizeof(aar.acr_att_intf) - 1) {
375 fprintf(stderr, "%s: Illegal interface name\n", prog);
376 exit(1);
380 * Find/validate requested signalling protocol
382 for (prp = protos; prp->p_name; prp++) {
383 if (strcasecmp(prp->p_name, argv[1]) == 0)
384 break;
386 if (prp->p_name == NULL) {
387 fprintf(stderr, "%s: Unknown signalling protocol\n", prog);
388 exit(1);
393 * Build ioctl request
395 aar.acr_opcode = AIOCS_CFG_ATT;
396 strncpy(aar.acr_att_intf, argv[0], sizeof(aar.acr_att_intf));
397 aar.acr_att_proto = prp->p_id;
400 * Tell the kernel to do the attach
402 s = socket(AF_ATM, SOCK_DGRAM, 0);
403 if (s < 0) {
404 sock_error(errno);
406 if (ioctl(s, AIOCCFG, (caddr_t)&aar) < 0) {
407 fprintf(stderr, "%s: ", prog);
408 switch (errno) {
409 case EINVAL:
410 case EOPNOTSUPP:
411 case EPROTONOSUPPORT:
412 perror("Internal error");
413 break;
414 case ENOMEM:
415 fprintf(stderr, "Kernel memory exhausted\n");
416 break;
417 case EEXIST:
418 fprintf(stderr, "Signalling manager already attached to %s\n",
419 argv[0]);
420 break;
421 case ENETDOWN:
422 fprintf(stderr, "ATM network is inoperable\n");
423 break;
424 case EPERM:
425 fprintf(stderr, "Must be super user to use attach subcommand\n");
426 break;
427 case ENXIO:
428 fprintf(stderr, "%s is not an ATM device\n",
429 argv[0]);
430 break;
431 case ETOOMANYREFS:
432 fprintf(stderr, "%s has too few or too many network interfaces\n",
433 argv[0]);
434 break;
435 default:
436 perror("Ioctl (AIOCCFG) attach");
437 break;
439 exit(1);
441 close(s);
446 * Process interface detach command
448 * Command format:
449 * atm detach <interface_name>
451 * Arguments:
452 * argc number of arguments to command
453 * argv pointer to argument strings
454 * cmdp pointer to command description
456 * Returns:
457 * none
460 static void
461 detach(__unused int argc, char **argv, __unused const struct cmd *cmdp)
463 struct atmcfgreq adr;
464 int s;
467 * Validate interface name
469 if (strlen(argv[0]) > sizeof(adr.acr_det_intf) - 1) {
470 fprintf(stderr, "%s: Illegal interface name\n", prog);
471 exit(1);
475 * Build ioctl request
477 adr.acr_opcode = AIOCS_CFG_DET;
478 strncpy(adr.acr_det_intf, argv[0], sizeof(adr.acr_det_intf));
481 * Tell the kernel to do the detach
483 s = socket(AF_ATM, SOCK_DGRAM, 0);
484 if (s < 0) {
485 sock_error(errno);
487 if (ioctl(s, AIOCCFG, (caddr_t)&adr) < 0) {
488 fprintf(stderr, "%s: ", prog);
489 switch (errno) {
490 case EALREADY:
491 fprintf(stderr, "Signalling manager already detaching from %s\n",
492 argv[0]);
493 break;
494 case EINVAL:
495 perror("Internal error");
496 break;
497 case EPERM:
498 fprintf(stderr, "Must be super user to use detach subcommand\n");
499 break;
500 default:
501 perror("ioctl (AIOCCFG) detach");
502 break;
504 exit(1);
506 close(s);
511 * Process PVC add command
513 * Command format:
514 * atm add PVC <interface_name> <vpi> <vci> <aal> <encaps>
515 * <owner_name>
517 * Arguments:
518 * argc number of arguments to command
519 * argv pointer to argument strings
520 * cmdp pointer to command description
522 * Returns:
523 * none
526 static void
527 pvc_add(int argc, char **argv, const struct cmd *cmdp)
529 struct atmaddreq apr;
530 struct atminfreq air;
531 struct air_int_rsp *int_info;
532 const struct owner *owp;
533 const struct aal *alp;
534 const struct encaps *enp;
535 char *cp;
536 long v;
537 int buf_len, s;
540 * Initialize opcode and flags
542 apr.aar_opcode = AIOCS_ADD_PVC;
543 apr.aar_pvc_flags = 0;
546 * Validate interface name and issue an information
547 * request IOCTL for the interface
549 if (strlen(argv[0]) > sizeof(apr.aar_pvc_intf) - 1) {
550 fprintf(stderr, "%s: Illegal interface name\n", prog);
551 exit(1);
553 UM_ZERO(air.air_int_intf, sizeof(air.air_int_intf));
554 strcpy(air.air_int_intf, argv[0]);
555 buf_len = sizeof(struct air_int_rsp);
556 air.air_opcode = AIOCS_INF_INT;
557 buf_len = do_info_ioctl(&air, buf_len);
558 if (buf_len < 0) {
559 fprintf(stderr, "%s: ", prog);
560 switch (errno) {
561 case ENOPROTOOPT:
562 case EOPNOTSUPP:
563 perror("Internal error");
564 break;
565 case ENXIO:
566 fprintf(stderr, "%s is not an ATM device\n",
567 argv[0]);
568 break;
569 default:
570 perror("ioctl (AIOCINFO)");
571 break;
573 exit(1);
575 int_info = (struct air_int_rsp *) air.air_buf_addr;
576 strcpy(apr.aar_pvc_intf, argv[0]);
577 argc--; argv++;
580 * Validate vpi/vci values
582 v = strtol(argv[0], &cp, 0);
583 if ((*cp != '\0') || (v < 0) || (v >= 1 << 8)) {
584 fprintf(stderr, "%s: Invalid VPI value\n", prog);
585 exit(1);
587 apr.aar_pvc_vpi = (u_short) v;
588 argc--; argv++;
590 v = strtol(argv[0], &cp, 0);
591 if ((*cp != '\0') || (v < MIN_VCI) || (v >= 1 << 16)) {
592 fprintf(stderr, "%s: Invalid VCI value\n", prog);
593 exit(1);
595 apr.aar_pvc_vci = (u_short) v;
596 argc--; argv++;
599 * Validate requested PVC AAL
601 for (alp = aals; alp->a_name; alp++) {
602 if (strcasecmp(alp->a_name, argv[0]) == 0)
603 break;
605 if (alp->a_name == NULL) {
606 fprintf(stderr, "%s: Invalid PVC AAL\n", prog);
607 exit(1);
609 apr.aar_pvc_aal = alp->a_id;
610 argc--; argv++;
613 * Validate requested PVC encapsulation
615 for (enp = encaps; enp->e_name; enp++) {
616 if (strcasecmp(enp->e_name, argv[0]) == 0)
617 break;
619 if (enp->e_name == NULL) {
620 fprintf(stderr, "%s: Invalid PVC encapsulation\n", prog);
621 exit(1);
623 apr.aar_pvc_encaps = enp->e_id;
624 argc--; argv++;
627 * Validate requested PVC owner
629 for (owp = owners; owp->o_name; owp++) {
630 if (strcasecmp(owp->o_name, argv[0]) == 0)
631 break;
633 if (owp->o_name == NULL) {
634 fprintf(stderr, "%s: Unknown PVC owner\n", prog);
635 exit(1);
637 apr.aar_pvc_sap = owp->o_sap;
638 argc--; argv++;
641 * Perform service user processing
643 if (owp->o_pvcadd) {
644 (*owp->o_pvcadd)(argc, argv, cmdp, &apr, int_info);
645 } else {
646 fprintf(stderr, "%s: Unsupported PVC owner\n", prog);
647 exit(1);
651 * Tell the kernel to add the PVC
653 s = socket(AF_ATM, SOCK_DGRAM, 0);
654 if (s < 0) {
655 sock_error(errno);
657 if (ioctl(s, AIOCADD, (caddr_t)&apr) < 0) {
658 fprintf(stderr, "%s: ", prog);
659 switch (errno) {
660 case EPROTONOSUPPORT:
661 case ENOPROTOOPT:
662 perror("Internal error");
663 break;
664 case EINVAL:
665 fprintf(stderr, "Invalid parameter\n");
666 break;
667 case EEXIST:
668 fprintf(stderr, "PVC already exists\n");
669 break;
670 case ENETDOWN:
671 fprintf(stderr, "ATM network is inoperable\n");
672 break;
673 case ENOMEM:
674 fprintf(stderr, "Kernel memory exhausted\n");
675 break;
676 case EPERM:
677 fprintf(stderr, "Must be super user to use add subcommand\n");
678 break;
679 case ERANGE:
680 fprintf(stderr, "Invalid VPI or VCI value\n");
681 break;
682 default:
683 perror("ioctl (AIOCADD) add PVC");
684 break;
686 exit(1);
688 close(s);
693 * Process ARP add command
695 * Command formats:
696 * atm add arp [<netif>] <IP addr> <ATM addr>
698 * Arguments:
699 * argc number of arguments to command
700 * argv pointer to argument strings
701 * cmdp pointer to command description
703 * Returns:
704 * none
707 static void
708 arp_add(int argc, char **argv, __unused const struct cmd *cmdp)
710 int len, s;
711 struct atmaddreq apr;
712 Atm_addr host_atm;
713 struct sockaddr_in *sin;
714 union {
715 struct sockaddr_in sin;
716 struct sockaddr sa;
717 } host_ip;
720 * Initialize add request structure
722 UM_ZERO(&apr, sizeof(apr));
725 * Get network interface name if one is present
727 if (argc == 3) {
728 check_netif_name(argv[0]);
729 strcpy(apr.aar_arp_intf, argv[0]);
730 argc--; argv++;
734 * Get IP address of specified host name
736 UM_ZERO(&host_ip, sizeof(host_ip));
737 host_ip.sa.sa_family = AF_INET;
738 sin = get_ip_addr(argv[0]);
739 host_ip.sin.sin_addr.s_addr = sin->sin_addr.s_addr;
740 argc--; argv++;
743 * Get specified ATM address
745 len = get_hex_atm_addr(argv[0], (u_char *)host_atm.address,
746 sizeof(Atm_addr_nsap));
747 switch(len) {
748 case sizeof(Atm_addr_nsap):
749 host_atm.address_format = T_ATM_ENDSYS_ADDR;
750 host_atm.address_length = sizeof(Atm_addr_nsap);
751 break;
752 case sizeof(Atm_addr_spans):
753 host_atm.address_format = T_ATM_SPANS_ADDR;
754 host_atm.address_length = sizeof(Atm_addr_spans);
755 break;
756 default:
757 fprintf(stderr, "%s: Invalid ATM address\n", prog);
758 exit(1);
762 * Build IOCTL request
764 apr.aar_opcode = AIOCS_ADD_ARP;
765 apr.aar_arp_dst = host_ip.sa;
766 ATM_ADDR_COPY(&host_atm, &apr.aar_arp_addr);
767 apr.aar_arp_origin = ARP_ORIG_PERM;
770 * Tell the kernel to add the ARP table entry
772 s = socket(AF_ATM, SOCK_DGRAM, 0);
773 if (s < 0) {
774 sock_error(errno);
776 if (ioctl(s, AIOCADD, (caddr_t)&apr) < 0) {
777 fprintf(stderr, "%s: ", prog);
778 switch (errno) {
779 case EINVAL:
780 fprintf(stderr, "Invalid parameter\n");
781 break;
782 case EPERM:
783 fprintf(stderr, "Must be super user to use add subcommand\n");
784 break;
785 case EADDRNOTAVAIL:
786 fprintf(stderr, "IP address not valid for interface\n");
787 break;
788 default:
789 perror("ioctl (AIOCADD) add");
790 break;
792 exit(1);
794 close(s);
799 * Process PVC delete command
801 * Command formats:
802 * atm delete pvc <interface_name> <vpi> <vci>
804 * Arguments:
805 * argc number of arguments to command
806 * argv pointer to argument strings
807 * cmdp pointer to command description
809 * Returns:
810 * none
813 static void
814 pvc_dlt(int argc, char **argv, const struct cmd *cmdp)
816 struct atmdelreq apr;
819 * Set opcode
821 apr.adr_opcode = AIOCS_DEL_PVC;
824 * Complete request by calling subroutine
826 vcc_dlt(argc, argv, cmdp, &apr);
831 * Process SVC delete command
833 * Command formats:
834 * atm delete svc <interface_name> <vpi> <vci>
836 * Arguments:
837 * argc number of arguments to command
838 * argv pointer to argument strings
839 * cmdp pointer to command description
841 * Returns:
842 * none
845 static void
846 svc_dlt(int argc, char **argv, const struct cmd *cmdp)
848 struct atmdelreq apr;
851 * Set opcode
853 apr.adr_opcode = AIOCS_DEL_SVC;
856 * Complete request by calling subroutine
858 vcc_dlt(argc, argv, cmdp, &apr);
863 * Complete an SVC or PVC delete command
865 * Arguments:
866 * argc number of arguments to command
867 * argv pointer to argument strings
868 * cmdp pointer to command description
869 * apr pointer to ATM delete IOCTL structure
871 * Returns:
872 * none
875 static void
876 vcc_dlt(int argc, char **argv, __unused const struct cmd *cmdp, struct atmdelreq *apr)
878 char *cp;
879 long v;
880 int s;
883 * Validate interface name
885 if (strlen(argv[0]) > sizeof(apr->adr_pvc_intf) - 1) {
886 fprintf(stderr, "%s: Illegal interface name\n", prog);
887 exit(1);
889 strcpy(apr->adr_pvc_intf, argv[0]);
890 argc--; argv++;
893 * Validate vpi/vci values
895 v = strtol(argv[0], &cp, 0);
896 if ((*cp != '\0') || (v < 0) || (v >= 1 << 8)) {
897 fprintf(stderr, "%s: Invalid VPI value\n", prog);
898 exit(1);
900 apr->adr_pvc_vpi = (u_short) v;
901 argc--; argv++;
903 v = strtol(argv[0], &cp, 0);
904 if ((*cp != '\0') || (v < MIN_VCI) || (v >= 1 << 16)) {
905 fprintf(stderr, "%s: Invalid VCI value\n", prog);
906 exit(1);
908 apr->adr_pvc_vci = (u_short) v;
909 argc--; argv++;
912 * Tell the kernel to delete the VCC
914 s = socket(AF_ATM, SOCK_DGRAM, 0);
915 if (s < 0) {
916 sock_error(errno);
918 if (ioctl(s, AIOCDEL, (caddr_t)apr) < 0) {
919 fprintf(stderr, "%s: ", prog);
920 switch (errno) {
921 case EINVAL:
922 fprintf(stderr, "Invalid parameter\n");
923 break;
924 case ENOENT:
925 fprintf(stderr, "VCC not found\n");
926 break;
927 case EALREADY:
928 fprintf(stderr, "VCC already being closed\n");
929 break;
930 case ENXIO:
931 fprintf(stderr, "%s is not an ATM device\n",
932 apr->adr_pvc_intf);
933 break;
934 case EPERM:
935 fprintf(stderr, "Must be super user to use delete subcommand\n");
936 break;
937 default:
938 perror("ioctl (AIOCDEL) delete");
939 break;
941 exit(1);
943 close(s);
948 * Process ARP delete command
950 * Command formats:
951 * atm delete arp <IP addr>
953 * Arguments:
954 * argc number of arguments to command
955 * argv pointer to argument strings
956 * cmdp pointer to command description
958 * Returns:
959 * none
962 static void
963 arp_dlt(int argc, char **argv, __unused const struct cmd *cmdp)
965 int s;
966 struct atmdelreq apr;
967 struct sockaddr_in *sin;
968 union {
969 struct sockaddr_in sin;
970 struct sockaddr sa;
971 } host_addr;
974 * Set opcode
976 UM_ZERO(&apr, sizeof(apr));
977 apr.adr_opcode = AIOCS_DEL_ARP;
980 * Get network interface name if one is present
982 if (argc == 2) {
983 check_netif_name(argv[0]);
984 strcpy(apr.adr_arp_intf, argv[0]);
985 argc--; argv++;
989 * Get IP address of specified host name
991 UM_ZERO(&host_addr, sizeof(host_addr));
992 host_addr.sa.sa_family = AF_INET;
993 sin = get_ip_addr(argv[0]);
994 host_addr.sin.sin_addr.s_addr = sin->sin_addr.s_addr;
995 apr.adr_arp_dst = host_addr.sa;
998 * Tell the kernel to delete the ARP table entry
1000 s = socket(AF_ATM, SOCK_DGRAM, 0);
1001 if (s < 0) {
1002 sock_error(errno);
1004 if (ioctl(s, AIOCDEL, (caddr_t)&apr) < 0) {
1005 fprintf(stderr, "%s: ", prog);
1006 switch (errno) {
1007 case EINVAL:
1008 fprintf(stderr, "Invalid parameter\n");
1009 break;
1010 case EPERM:
1011 fprintf(stderr, "Must be super user to use delete subcommand\n");
1012 break;
1013 default:
1014 perror("ioctl (AIOCDEL) delete");
1015 break;
1017 exit(1);
1019 close(s);
1024 * Process help command
1026 * Arguments:
1027 * argc number of arguments to command
1028 * argv pointer to argument strings
1029 * cmdp pointer to command description
1031 * Returns:
1032 * none
1035 static void
1036 help(__unused int argc, __unused char **argv, __unused const struct cmd *cmdp)
1038 usage(cmds, "");