Another round of typo fixes (mostly in messages).
[dragonfly.git] / sbin / atm / atm / atm_set.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
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.
12  *
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.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sbin/atm/atm/atm_set.c,v 1.3.2.1 2000/07/01 06:02:14 ps Exp $
27  *      @(#) $DragonFly: src/sbin/atm/atm/atm_set.c,v 1.7 2008/04/20 13:44:24 swildner Exp $
28  */
29
30 /*
31  * User configuration and display program
32  * --------------------------------------
33  *
34  * Routines for "set" subcommand
35  *
36  */
37
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_ioctl.h>
49
50 #include <errno.h>
51 #include <libatm.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <unistd.h>
56
57 #include "atm.h"
58
59 /*
60  * Process ATM ARP server set command
61  *
62  * Command format:
63  *      atm set arpserver <interface_name> <atm-address> <IP prefix> ...
64  *
65  * Arguments:
66  *      argc    number of arguments to command
67  *      argv    pointer to argument strings
68  *      cmdp    pointer to command description
69  *
70  * Returns:
71  *      none
72  *
73  */
74 void
75 set_arpserver(int argc, char **argv, __unused const struct cmd *cmdp)
76 {
77         int                     i, len, prefix_len = 0, rc, s;
78         char                    *intf;
79         Atm_addr                server;
80         struct sockaddr_in      *lis;
81         struct sockaddr_in      if_mask;
82         struct atmsetreq        asr;
83         struct atminfreq        air;
84         struct air_netif_rsp    *int_info;
85         struct {
86                 struct in_addr  ip_addr;
87                 struct in_addr  ip_mask;
88         } prefix_buf[64];
89
90         /*
91          * Validate interface name
92          */
93         check_netif_name(argv[0]);
94         intf = argv[0];
95         argc--; argv++;
96
97         /*
98          * Get the ARP server's ATM address
99          */
100         UM_ZERO(&server, sizeof(server));
101         if (strcasecmp(argv[0], "local")) {
102                 /*
103                  * ARP server NSAP address is provided
104                  */
105                 server.address_format = T_ATM_ENDSYS_ADDR;
106                 server.address_length = sizeof(Atm_addr_nsap);
107                 if (get_hex_atm_addr(argv[0],
108                                         (u_char *)server.address,
109                                         sizeof(Atm_addr_nsap)) !=
110                                 sizeof(Atm_addr_nsap)) {
111                         fprintf(stderr, "%s: Invalid ARP server address\n",
112                                         prog);
113                         exit(1);
114                 }
115                 if (argc > 1) {
116                         fprintf(stderr, "%s: Invalid number of arguments\n",
117                                         prog);
118                         exit(1);
119                 }
120                 prefix_len = 0;
121         } else {
122                 argc--; argv++;
123
124                 /*
125                  * This host is the ARP server
126                  */
127                 server.address_format = T_ATM_ABSENT;
128                 server.address_length = 0;
129
130                 /*
131                  * Get interface information from the kernel.  We need
132                  * to get the IP address and the subnet mask associated
133                  * with the network interface and insert them into the
134                  * list of permitted LIS prefixes.
135                  */
136                 len = sizeof(struct air_netif_rsp);
137                 UM_ZERO(&air, sizeof(air));
138                 air.air_opcode = AIOCS_INF_NIF;
139                 strcpy(air.air_int_intf, intf);
140                 len = do_info_ioctl(&air, len);
141                 if (len < 0) {
142                         fprintf(stderr, "%s: ", prog);
143                         switch (errno) {
144                         case ENOPROTOOPT:
145                         case EOPNOTSUPP:
146                                 perror("Internal error");
147                                 break;
148                         case ENXIO:
149                                 fprintf(stderr, "%s is not an ATM device\n",
150                                                 intf);
151                                 break;
152                         default:
153                                 perror("ioctl (AIOCINFO)");
154                                 break;
155                         }
156                         exit(1);
157                 }
158                 int_info = (struct air_netif_rsp *) air.air_buf_addr;
159                 lis = (struct sockaddr_in *)&int_info->anp_proto_addr;
160                 prefix_buf[0].ip_addr = lis->sin_addr;
161                 UM_FREE(int_info);
162         
163                 rc = get_subnet_mask(intf, &if_mask);
164                 if (rc) {
165                         fprintf(stderr, "%s: Can't get subnet mask for %s\n",
166                                         prog, intf);
167                 }
168                 prefix_buf[0].ip_mask = if_mask.sin_addr;
169                 prefix_buf[0].ip_addr.s_addr &=
170                                 prefix_buf[0].ip_mask.s_addr;
171
172                 /*
173                  * Get the prefixes of the LISs that we'll support
174                  */
175                 for (i = 1; argc; i++, argc--, argv++) {
176                         rc = parse_ip_prefix(argv[0],
177                                         (struct in_addr *)&prefix_buf[i]);
178                         if (rc != 0) {
179                                 fprintf(stderr, "%s: Invalid IP prefix value \'%s\'\n",
180                                         prog, argv[0]);
181                                 exit(1);
182                         }
183                 }
184
185                 /*
186                  * Compress the prefix list
187                  */
188                 prefix_len = compress_prefix_list((struct in_addr *)prefix_buf,
189                                 i * sizeof(struct in_addr) * 2);
190         }
191
192         /*
193          * Build ioctl request
194          */
195         UM_ZERO(&asr, sizeof(asr));
196         asr.asr_opcode = AIOCS_SET_ASV;
197         strncpy(asr.asr_arp_intf, intf, sizeof(asr.asr_arp_intf));
198         asr.asr_arp_addr = server;
199         asr.asr_arp_subaddr.address_format = T_ATM_ABSENT;
200         asr.asr_arp_subaddr.address_length = 0;
201         if (prefix_len)
202                 asr.asr_arp_pbuf = (caddr_t)prefix_buf;
203         else
204                 asr.asr_arp_pbuf = (caddr_t)0;
205         asr.asr_arp_plen = prefix_len;
206
207         /*
208          * Pass the new ARP server address to the kernel
209          */
210         s = socket(AF_ATM, SOCK_DGRAM, 0);
211         if (s < 0) {
212                 sock_error(errno);
213         }
214         if (ioctl(s, AIOCSET, (caddr_t)&asr) < 0) {
215                 fprintf(stderr, "%s: ", prog);
216                 switch (errno) {
217                 case EOPNOTSUPP:
218                 case EPROTONOSUPPORT:
219                         perror("Internal error");
220                         break;
221                 case EINVAL:
222                         fprintf(stderr, "Invalid parameter\n");
223                         break;
224                 case ENOMEM:
225                         fprintf(stderr, "Kernel memory exhausted\n");
226                         break;
227                 case ENETDOWN:
228                         fprintf(stderr, "ATM network is inoperable\n");
229                         break;
230                 case EPERM:
231                         fprintf(stderr, "Must be super user to use set subcommand\n");
232                         break;
233                 case ENXIO:
234                         fprintf(stderr, "%s is not an ATM interface\n", intf);
235                         break;
236                 case ENOENT:
237                         fprintf(stderr, "Signalling manager not attached\n");
238                         break;
239                 case ENOPROTOOPT:
240                         fprintf(stderr,
241                                 "%s does not have an IP address configured\n",
242                                 intf);
243                         break;
244                 default:
245                         perror("Ioctl (AIOCSET) ARPSERVER address");
246                         break;
247                 }
248                 exit(1);
249         }
250
251         close(s);
252 }
253
254
255 /*
256  * Process set MAC address command
257  *
258  * Command format:
259  *      atm set mac <interface_name> <MAC address>
260  *
261  * Arguments:
262  *      argc    number of remaining arguments to command
263  *      argv    pointer to remaining argument strings
264  *      cmdp    pointer to command description
265  *
266  * Returns:
267  *      none
268  *
269  */
270 void
271 set_macaddr(int argc, char **argv, __unused const struct cmd *cmdp)
272 {
273         int                     s;
274         char                    *intf;
275         struct mac_addr         mac;
276         struct atmsetreq        asr;
277
278         /*
279          * Validate interface name
280          */
281         if (strlen(argv[0]) > sizeof(asr.asr_mac_intf) - 1) {
282                 fprintf(stderr, "%s: Illegal interface name\n", prog);
283                 exit(1);
284         }
285         intf = argv[0];
286         argc--; argv++;
287
288         /*
289          * Get the MAC address provided by the user
290          */
291         if (get_hex_atm_addr(argv[0], (u_char *)&mac, sizeof(mac)) !=
292                         sizeof(mac)) {
293                 fprintf(stderr, "%s: Invalid MAC address\n", prog);
294                 exit(1);
295         }
296
297         /*
298          * Build ioctl request
299          */
300         asr.asr_opcode = AIOCS_SET_MAC;
301         strncpy(asr.asr_mac_intf, intf, sizeof(asr.asr_mac_intf));
302         UM_COPY(&mac, &asr.asr_mac_addr, sizeof(asr.asr_mac_addr));
303
304         /*
305          * Pass the new address to the kernel
306          */
307         s = socket(AF_ATM, SOCK_DGRAM, 0);
308         if (s < 0) {
309                 sock_error(errno);
310         }
311         if (ioctl(s, AIOCSET, (caddr_t)&asr) < 0) {
312                 fprintf(stderr, "%s: ", prog);
313                 switch (errno) {
314                 case EOPNOTSUPP:
315                 case EPROTONOSUPPORT:
316                         perror("Internal error");
317                         break;
318                 case EADDRINUSE:
319                         fprintf(stderr, "Interface must be detached to set MAC address\n");
320                         break;
321                 case EINVAL:
322                         fprintf(stderr, "Invalid parameter\n");
323                         break;
324                 case ENOMEM:
325                         fprintf(stderr, "Kernel memory exhausted\n");
326                         break;
327                 case ENETDOWN:
328                         fprintf(stderr, "ATM network is inoperable\n");
329                         break;
330                 case EPERM:
331                         fprintf(stderr, "Must be super user to use set subcommand\n");
332                         break;
333                 case ENXIO:
334                         fprintf(stderr, "%s is not an ATM device\n",
335                                         argv[0]);
336                         break;
337                 default:
338                         perror("Ioctl (AIOCSET) MAC address");
339                         break;
340                 }
341                 exit(1);
342         }
343
344         close(s);
345 }
346
347
348 /*
349  * Process network interface set command
350  *
351  * Command format:
352  *      atm set netif <interface_name> <prefix_name> <count>
353  *
354  * Arguments:
355  *      argc    number of arguments to command
356  *      argv    pointer to argument strings
357  *      cmdp    pointer to command description
358  *
359  * Returns:
360  *      none
361  *
362  */
363 void
364 set_netif(int argc, char **argv, __unused const struct cmd *cmdp)
365 {
366         struct atmsetreq        anr;
367         char                    str[16];
368         char                    *cp;
369         int                     nifs, s;
370
371         /*
372          * Set IOCTL opcode
373          */
374         anr.asr_opcode = AIOCS_SET_NIF;
375
376         /*
377          * Validate interface name
378          */
379         if (strlen(argv[0]) > sizeof(anr.asr_nif_intf) - 1) {
380                 fprintf(stderr, "%s: Illegal interface name\n", prog);
381                 exit(1);
382         }
383         strcpy(anr.asr_nif_intf, argv[0]);
384         argc--; argv++;
385
386         /*
387          * Validate network interface name prefix
388          */
389         if ((strlen(argv[0]) > sizeof(anr.asr_nif_pref) - 1) ||
390                         (strpbrk(argv[0], "0123456789"))) {
391                 fprintf(stderr, "%s: Illegal network interface prefix\n", prog);
392                 exit(1);
393         }
394         strcpy(anr.asr_nif_pref, argv[0]);
395         argc--; argv++;
396
397         /*
398          * Validate interface count
399          */
400         nifs = (int) strtol(argv[0], &cp, 0);
401         if ((*cp != '\0') || (nifs < 0) || (nifs > MAX_NIFS)) {
402                 fprintf(stderr, "%s: Invalid interface count\n", prog);
403                 exit(1);
404         }
405         anr.asr_nif_cnt = nifs;
406
407         /*
408          * Make sure the resulting name won't be too long
409          */
410         sprintf(str, "%d", nifs - 1);
411         if ((strlen(str) + strlen(anr.asr_nif_pref)) >
412                         sizeof(anr.asr_nif_intf) - 1) {
413                 fprintf(stderr, "%s: Network interface prefix too long\n", prog);
414                 exit(1);
415         }
416
417         /*
418          * Tell the kernel to do it
419          */
420         s = socket(AF_ATM, SOCK_DGRAM, 0);
421         if (s < 0) {
422                 sock_error(errno);
423         }
424         if (ioctl(s, AIOCSET, (caddr_t)&anr) < 0) {
425                 fprintf(stderr, "%s: ", prog);
426                 perror("ioctl (AIOCSET) set NIF");
427                 exit(1);
428         }
429         close(s);
430 }
431
432
433 /*
434  * Process set NSAP prefix command
435  *
436  * Command format:
437  *      atm set nsap <interface_name> <NSAP prefix>
438  *
439  * Arguments:
440  *      argc    number of remaining arguments to command
441  *      argv    pointer to remaining argument strings
442  *      cmdp    pointer to command description
443  *
444  * Returns:
445  *      none
446  *
447  */
448 void
449 set_prefix(int argc, char **argv, __unused const struct cmd *cmdp)
450 {
451         int                     s;
452         char                    *intf;
453         u_char                  pfix[13];
454         struct atmsetreq        asr;
455
456         /*
457          * Validate interface name
458          */
459         if (strlen(argv[0]) > sizeof(asr.asr_prf_intf) - 1) {
460                 fprintf(stderr, "%s: Illegal interface name\n", prog);
461                 exit(1);
462         }
463         intf = argv[0];
464         argc--; argv++;
465
466         /*
467          * Get the prefix provided by the user
468          */
469         if (get_hex_atm_addr(argv[0], pfix, sizeof(pfix)) !=
470                         sizeof(pfix)) {
471                 fprintf(stderr, "%s: Invalid NSAP prefix\n", prog);
472                 exit(1);
473         }
474
475         /*
476          * Build ioctl request
477          */
478         asr.asr_opcode = AIOCS_SET_PRF;
479         strncpy(asr.asr_prf_intf, intf, sizeof(asr.asr_prf_intf));
480         UM_COPY(pfix, asr.asr_prf_pref, sizeof(asr.asr_prf_pref));
481
482         /*
483          * Pass the new prefix to the kernel
484          */
485         s = socket(AF_ATM, SOCK_DGRAM, 0);
486         if (s < 0) {
487                 sock_error(errno);
488         }
489         if (ioctl(s, AIOCSET, (caddr_t)&asr) < 0) {
490                 fprintf(stderr, "%s: ", prog);
491                 switch (errno) {
492                 case EOPNOTSUPP:
493                 case EPROTONOSUPPORT:
494                         perror("Internal error");
495                         break;
496                 case EALREADY:
497                         fprintf(stderr, "NSAP prefix is already set\n");
498                         break;
499                 case EINVAL:
500                         fprintf(stderr, "Invalid parameter\n");
501                         break;
502                 case ENOMEM:
503                         fprintf(stderr, "Kernel memory exhausted\n");
504                         break;
505                 case ENETDOWN:
506                         fprintf(stderr, "ATM network is inoperable\n");
507                         break;
508                 case EPERM:
509                         fprintf(stderr, "Must be super user to use set subcommand\n");
510                         break;
511                 case ENXIO:
512                         fprintf(stderr, "%s is not an ATM device\n",
513                                         argv[0]);
514                         break;
515                 default:
516                         perror("Ioctl (AIOCSET) NSAP prefix");
517                         break;
518                 }
519                 exit(1);
520         }
521
522         close(s);
523 }