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.
28 * User configuration and display program
29 * --------------------------------------
35 #include <sys/param.h>
36 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <netatm/port.h>
40 #include <netatm/atm.h>
41 #include <netatm/atm_if.h>
42 #include <netatm/atm_sap.h>
43 #include <netatm/atm_sys.h>
44 #include <netatm/atm_ioctl.h>
45 #include <arpa/inet.h>
56 __RCSID("@(#) $FreeBSD$");
61 * Table entry definition
70 * Table to translate vendor codes to ASCII
72 static const tbl_ent vendors[] = {
73 { VENDOR_UNKNOWN, "Unknown" },
74 { VENDOR_FORE, "Fore" },
75 { VENDOR_ENI, "ENI" },
76 { VENDOR_IDT, "IDT" },
77 { VENDOR_PROSUM, "ProSum" },
78 { VENDOR_NETGRAPH, "Netgraph" },
84 * Table to translate adapter codes to ASCII
86 static const tbl_ent adapter_types[] = {
87 { DEV_UNKNOWN, "Unknown" },
88 { DEV_FORE_SBA200E, "SBA-200E" },
89 { DEV_FORE_SBA200, "SBA-200" },
90 { DEV_FORE_PCA200E, "PCA-200E" },
91 { DEV_FORE_ESA200E, "ESA-200E" },
92 { DEV_ENI_155P, "ENI-155p" },
93 { DEV_IDT_155, "IDT" },
94 { DEV_PROATM_25, "PROATM-25" },
95 { DEV_PROATM_155, "PROATM-155" },
96 { DEV_VATMPIF, "VATMPIF" },
97 { DEV_FORE_LE25, "ForeLE-25" },
98 { DEV_FORE_LE155, "ForeLE-155" },
99 { DEV_IDT_25, "NICStAR-25" },
100 { DEV_IDTABR_25, "IDT77252-25" },
101 { DEV_IDTABR_155, "IDT77252-155" },
102 { DEV_FORE_HE155, "ForeHE-155" },
103 { DEV_FORE_HE622, "ForeHE-622" },
108 * Table to translate medium types to ASCII
110 static const tbl_ent media_types[] = {
111 { MEDIA_UNKNOWN, "Unknown" },
112 { MEDIA_TAXI_100, "100 Mbps 4B/5B" },
113 { MEDIA_TAXI_140, "140 Mbps 4B/5B" },
114 { MEDIA_OC3C, "OC-3c" },
115 { MEDIA_OC12C, "OC-12c" },
116 { MEDIA_UTP155, "155 Mbps UTP" },
117 { MEDIA_UTP25, "25.6 Mbps UTP" },
118 { MEDIA_VIRTUAL, "Virtual Link" },
119 { MEDIA_DSL, "xDSL" },
124 * Table to translate bus types to ASCII
126 static const tbl_ent bus_types[] = {
127 { BUS_UNKNOWN, "Unknown" },
128 { BUS_SBUS_B16, "SBus" },
129 { BUS_SBUS_B32, "SBus" },
131 { BUS_EISA, "EISA" },
133 { BUS_VIRTUAL, "Virtual" },
139 * Get interface vendor name
141 * Return a character string with a vendor name, given a vendor code.
147 * char * pointer to a string with the vendor name
151 get_vendor(int vendor)
155 for(i=0; vendors[i].name; i++) {
156 if (vendors[i].type == vendor)
157 return(vendors[i].name);
171 * char * pointer to a string with the adapter type
179 for(i=0; adapter_types[i].name; i++) {
180 if (adapter_types[i].type == dev)
181 return(adapter_types[i].name);
189 * Get communication medium type
195 * char * pointer to a string with the name of the medium
199 get_media_type(int media)
203 for(i=0; media_types[i].name; i++) {
204 if (media_types[i].type == media)
205 return(media_types[i].name);
219 * char * pointer to a string with the bus type
223 get_bus_type(int bus)
227 for(i=0; bus_types[i].name; i++) {
228 if (bus_types[i].type == bus)
229 return(bus_types[i].name);
239 * Get a string giving the adapter's vendor and type.
242 * intf interface name
245 * char * pointer to a string identifying the adapter
249 get_adapter_name(const char *intf)
252 struct atminfreq air;
253 struct air_cfg_rsp *cfg;
254 static char name[256];
259 bzero(&air, sizeof(air));
260 bzero(name, sizeof(name));
263 * Get configuration information from the kernel
265 air.air_opcode = AIOCS_INF_CFG;
266 strcpy(air.air_cfg_intf, intf);
267 buf_len = do_info_ioctl(&air, sizeof(struct air_cfg_rsp));
268 if (buf_len < sizeof(struct air_cfg_rsp))
270 cfg = (struct air_cfg_rsp *)(void *)air.air_buf_addr;
273 * Build a string describing the adapter
275 strcpy(name, get_vendor(cfg->acp_vendor));
277 strcat(name, get_adapter(cfg->acp_device));
286 * Format a MAC address into a string
289 * addr pointer to a MAC address
292 * the address of a string representing the MAC address
296 format_mac_addr(const Mac_addr *addr)
298 static char str[256];
301 * Check for null pointer
307 * Clear the returned string
309 bzero(str, sizeof(str));
314 sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
327 * Parse an IP prefix designation in the form nnn.nnn.nnn.nnn/mm
330 * cp pointer to prefix designation string
331 * op pointer to a pair of in_addrs for the result
335 * -1 prefix was invalid
339 parse_ip_prefix(const char *cp, struct in_addr *op)
343 struct in_addr ip_addr;
345 static u_long masks[33] = {
382 * Find the slash that marks the start of the mask
384 mp = strchr(cp, '/');
391 * Convert the IP-address part of the prefix
393 ip_addr.s_addr = inet_addr(cp);
394 if (ip_addr.s_addr == INADDR_NONE)
398 * Set the default mask length
400 if (IN_CLASSA(ntohl(ip_addr.s_addr)))
402 else if (IN_CLASSB(ntohl(ip_addr.s_addr)))
404 else if (IN_CLASSC(ntohl(ip_addr.s_addr)))
410 * Get the mask length
414 if (len < 1 || len > 32)
419 * Select the mask and copy the IP address into the
420 * result buffer, ANDing it with the mask
422 op[1].s_addr = htonl(masks[len]);
423 op[0].s_addr = ip_addr.s_addr & op[1].s_addr;
430 * Compress a list of IP network prefixes
433 * ipp pointer to list of IP address/mask pairs
437 * length of compressed list
441 compress_prefix_list(struct in_addr *ipp, size_t ilen)
444 struct in_addr *ip1, *ip2, *m1, *m2;
447 * Figure out how many pairs there are
449 n = ilen / (sizeof(struct in_addr) * 2);
452 * Check each pair of address/mask pairs to make sure
453 * none contains the other
455 for (i = 0; i < n; i++) {
460 * If we've already eliminated this address,
463 if (ip1->s_addr == 0)
467 * Try all possible second members of the pair
469 for (j = i + 1; j < n; j++) {
474 * If we've already eliminated the second
475 * address, just skip the checks
477 if (ip2->s_addr == 0)
481 * Compare the address/mask pairs
483 if (m1->s_addr == m2->s_addr) {
487 if (ip1->s_addr == ip2->s_addr) {
491 } else if (ntohl(m1->s_addr) <
496 if ((ip2->s_addr & m1->s_addr) ==
505 if ((ip1->s_addr & m2->s_addr) ==
516 * Now pull up the list, eliminating zeroed entries
518 for (i = 0, j = 0; i < n; i++) {
523 if (ip1->s_addr != 0) {
532 return(j * sizeof(struct in_addr) * 2);
537 * Make sure a user-supplied parameter is a valid network interface
540 * When a socket call fails, print an error message and exit
543 * nif pointer to network interface name
546 * none exits if name is not valid
550 check_netif_name(const char *nif)
555 * Look up the name in the kernel
557 rc = verify_nif_name(nif);
567 } else if (rc == 0) {
571 fprintf(stderr, "%s: Invalid network interface name %s\n",
575 * Error performing IOCTL
577 fprintf(stderr, "%s: ", prog);
581 perror("Internal error");
584 fprintf(stderr, "%s is not an ATM device\n",
588 perror("ioctl (AIOCINFO)");
598 * Socket error handler
600 * When a socket call fails, print an error message and exit
603 * err an errno describing the error
612 fprintf(stderr, "%s: ", prog);
616 case EPROTONOSUPPORT:
617 fprintf(stderr, "ATM protocol support not loaded\n");