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_subr.c,v 1.3.2.1 2000/07/01 06:02:14 ps Exp $
27 * @(#) $DragonFly: src/sbin/atm/atm/atm_subr.c,v 1.4 2006/10/16 00:15:35 pavalos Exp $
31 * User configuration and display program
32 * --------------------------------------
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_ioctl.h>
48 #include <arpa/inet.h>
59 * Table entry definition
68 * Table to translate vendor codes to ASCII
70 static const tbl_ent vendors
[] = {
71 { VENDAPI_UNKNOWN
, "Unknown" },
72 { VENDAPI_FORE_1
, "Fore" },
73 { VENDAPI_ENI_1
, "ENI" },
79 * Table to translate adapter codes to ASCII
81 static const tbl_ent adapter_types
[] = {
82 { DEV_UNKNOWN
, "Unknown" },
83 { DEV_FORE_SBA200E
, "SBA-200E" },
84 { DEV_FORE_SBA200
, "SBA-200" },
85 { DEV_FORE_PCA200E
, "PCA-200E" },
86 { DEV_ENI_155P
, "ENI-155p" },
91 * Table to translate medium types to ASCII
93 static const tbl_ent media_types
[] = {
94 { MEDIA_UNKNOWN
, "Unknown" },
95 { MEDIA_TAXI_100
, "100 Mbps 4B/5B" },
96 { MEDIA_TAXI_140
, "140 Mbps 4B/5B" },
97 { MEDIA_OC3C
, "OC-3c" },
98 { MEDIA_OC12C
, "OC-12c" },
99 { MEDIA_UTP155
, "155 Mbps UTP" },
104 * Table to translate bus types to ASCII
106 static const tbl_ent bus_types
[] = {
107 { BUS_UNKNOWN
, "Unknown" },
108 { BUS_SBUS_B16
, "SBus" },
109 { BUS_SBUS_B32
, "SBus" },
116 * Get interface vendor name
118 * Return a character string with a vendor name, given a vendor code.
124 * char * pointer to a string with the vendor name
128 get_vendor(int vendor
)
132 for(i
=0; vendors
[i
].name
; i
++) {
133 if (vendors
[i
].type
== vendor
)
134 return(vendors
[i
].name
);
148 * char * pointer to a string with the adapter type
156 for(i
=0; adapter_types
[i
].name
; i
++) {
157 if (adapter_types
[i
].type
== dev
)
158 return(adapter_types
[i
].name
);
166 * Get communication medium type
172 * char * pointer to a string with the name of the medium
176 get_media_type(int media
)
180 for(i
=0; media_types
[i
].name
; i
++) {
181 if (media_types
[i
].type
== media
)
182 return(media_types
[i
].name
);
196 * char * pointer to a string with the bus type
200 get_bus_type(int bus
)
204 for(i
=0; bus_types
[i
].name
; i
++) {
205 if (bus_types
[i
].type
== bus
)
206 return(bus_types
[i
].name
);
216 * Get a string giving the adapter's vendor and type.
219 * intf interface name
222 * char * pointer to a string identifying the adapter
226 get_adapter_name(char *intf
)
229 struct atminfreq air
;
230 struct air_cfg_rsp
*cfg
;
231 static char name
[256];
236 UM_ZERO(&air
, sizeof(air
));
237 UM_ZERO(name
, sizeof(name
));
240 * Get configuration information from the kernel
242 air
.air_opcode
= AIOCS_INF_CFG
;
243 strcpy(air
.air_cfg_intf
, intf
);
244 buf_len
= do_info_ioctl(&air
, sizeof(struct air_cfg_rsp
));
245 if ((size_t)buf_len
< sizeof(struct air_cfg_rsp
))
247 cfg
= (struct air_cfg_rsp
*) air
.air_buf_addr
;
250 * Build a string describing the adapter
252 strcpy(name
, get_vendor(cfg
->acp_vendor
));
254 strcat(name
, get_adapter(cfg
->acp_device
));
263 * Format a MAC address into a string
266 * addr pointer to a MAC address
269 * the address of a string representing the MAC address
273 format_mac_addr(Mac_addr
*addr
)
275 static char str
[256];
278 * Check for null pointer
284 * Clear the returned string
286 UM_ZERO(str
, sizeof(str
));
291 sprintf(str
, "%02x:%02x:%02x:%02x:%02x:%02x",
304 * Parse an IP prefix designation in the form nnn.nnn.nnn.nnn/mm
307 * cp pointer to prefix designation string
308 * op pointer to a pair of in_addrs for the result
312 * -1 prefix was invalid
316 parse_ip_prefix(char *cp
, struct in_addr
*op
)
320 struct in_addr ip_addr
;
322 static u_long masks
[33] = {
359 * Find the slash that marks the start of the mask
361 mp
= strchr(cp
, '/');
368 * Convert the IP-address part of the prefix
370 ip_addr
.s_addr
= inet_addr(cp
);
371 if (ip_addr
.s_addr
== INADDR_NONE
)
375 * Set the default mask length
377 if (IN_CLASSA(ntohl(ip_addr
.s_addr
)))
379 else if (IN_CLASSB(ntohl(ip_addr
.s_addr
)))
381 else if (IN_CLASSC(ntohl(ip_addr
.s_addr
)))
387 * Get the mask length
391 if (len
< 1 || len
> 32)
396 * Select the mask and copy the IP address into the
397 * result buffer, ANDing it with the mask
399 op
[1].s_addr
= htonl(masks
[len
]);
400 op
[0].s_addr
= ip_addr
.s_addr
& op
[1].s_addr
;
407 * Compress a list of IP network prefixes
410 * ipp pointer to list of IP address/mask pairs
414 * length of compressed list
418 compress_prefix_list(struct in_addr
*ipp
, int ilen
)
421 struct in_addr
*ip1
, *ip2
, *m1
, *m2
;
424 * Figure out how many pairs there are
426 n
= ilen
/ (sizeof(struct in_addr
) * 2);
429 * Check each pair of address/mask pairs to make sure
430 * none contains the other
432 for (i
= 0; i
< n
; i
++) {
437 * If we've already eliminated this address,
440 if (ip1
->s_addr
== 0)
444 * Try all possible second members of the pair
446 for (j
= i
+ 1; j
< n
; j
++) {
451 * If we've already eliminated the second
452 * address, just skip the checks
454 if (ip2
->s_addr
== 0)
458 * Compare the address/mask pairs
460 if (m1
->s_addr
== m2
->s_addr
) {
464 if (ip1
->s_addr
== ip2
->s_addr
) {
468 } else if (ntohl(m1
->s_addr
) <
473 if ((ip2
->s_addr
& m1
->s_addr
) ==
482 if ((ip1
->s_addr
& m2
->s_addr
) ==
493 * Now pull up the list, eliminating zeroed entries
495 for (i
= 0, j
= 0; i
< n
; i
++) {
500 if (ip1
->s_addr
!= 0) {
509 return(j
* sizeof(struct in_addr
) * 2);
514 * Make sure a user-supplied parameter is a valid network interface
517 * When a socket call fails, print an error message and exit
520 * nif pointer to network interface name
523 * none exits if name is not valid
527 check_netif_name(char *nif
)
532 * Look up the name in the kernel
534 rc
= verify_nif_name(nif
);
544 } else if (rc
== 0) {
548 fprintf(stderr
, "%s: Invalid network interface name %s\n",
552 * Error performing IOCTL
554 fprintf(stderr
, "%s: ", prog
);
558 perror("Internal error");
561 fprintf(stderr
, "%s is not an ATM device\n",
565 perror("ioctl (AIOCINFO)");
575 * Socket error handler
577 * When a socket call fails, print an error message and exit
580 * err an errno describing the error
589 fprintf(stderr
, "%s: ", prog
);
593 case EPROTONOSUPPORT
:
594 fprintf(stderr
, "ATM protocol support not loaded\n");