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