*** 1.1	1995/04/27 22:48:45
--- if.c	1995/05/05 03:19:50
***************
*** 6,11 ****
--- 6,12 ----
  
  #ifndef lint
  static	char sccsid[] = "@(#)if.c 1.1 92/07/30 SMI"; /* from UCB 5.3 4/23/86 */
+ /* plus MULTICAST 3.5 */
  #endif
  
  #include <stdio.h>
***************
*** 18,23 ****
--- 19,26 ----
  #ifdef	ENABLE_XNS
  #include <netns/ns.h>
  #endif	ENABLE_XNS
+ #define MULTICAST 1
+ #include <netinet/if_ether.h>
  
  #include <stdio.h>
  
***************
*** 29,34 ****
--- 32,39 ----
  extern	int kread();
  extern	char *routename(), *netname();
  
+ char *etherprint();
+ 
  /*
   * Print a description of the network interfaces.
   */
***************
*** 42,47 ****
--- 47,54 ----
  		struct in_ifaddr in;
  	} ifaddr;
  	off_t ifaddraddr;
+ 	off_t ifaddrfound;
+ 	off_t ifnetfound;
  	char name[16];
  
  	if (ifnetaddr == 0) {
***************
*** 71,76 ****
--- 78,84 ----
  		struct in_addr in, inet_makeaddr();
  		char buf[80];
  
+ 		ifnetfound = ifnetaddr;
  		if (ifaddraddr == 0) {
  			/*
  			 * No address list for the current interface:
***************
*** 111,116 ****
--- 119,125 ----
  
  			ifaddraddr = (off_t)ifnet.if_addrlist;
  		}
+ 		ifaddrfound = ifaddraddr;
  		if (ifaddraddr == 0) {
  			/*
  			 * There's no address associated with the current
***************
*** 219,224 ****
--- 228,297 ----
  		else
  			printf(" %-6d", ifnet.if_snd.ifq_len);
  		putchar('\n');
+ 
+ 		if (aflag && ifaddrfound) {
+ 			/*
+ 			 * print any internet multicast addresses
+ 			 */
+ 			switch (ifaddr.ifa.ifa_addr.sa_family) {
+ 			case AF_INET:
+ 			    {
+ 				off_t multiaddr;
+ 				struct in_multi inm;
+  
+ 				multiaddr = (off_t)ifaddr.in.ia_multiaddrs;
+ 				while (multiaddr != 0) {
+ 					kread(multiaddr, (char *)&inm,
+ 							sizeof inm);
+ 					multiaddr = (off_t)inm.inm_next;
+ 					printf("%23s %-19.19s\n", "",
+ 						routename(inm.inm_addr));
+ 				}
+ 				break;
+ 			    }
+ 			default:
+ 				break;
+ 			}
+ 		}
+ 		if (aflag && ifaddraddr == 0) {
+ 			/*
+ 			 * print link-level addresses
+ 			 * (Is there a better way to determine
+ 			 *  the type of network??)
+ 			 */
+ 			if (strncmp(name, "qe", 2) == 0 ||    /* Ethernet */
+ 			    strncmp(name, "de", 2) == 0 ||
+ 			    strncmp(name, "ex", 2) == 0 ||
+ 			    strncmp(name, "il", 2) == 0 ||
+ 			    strncmp(name, "le", 2) == 0 ||
+ 			    strncmp(name, "se", 2) == 0 ||
+ 			    strncmp(name, "ie", 2) == 0) {
+ 			    /* "ec", the 3Com interface for Suns, is not    */
+ 			    /* included, although it does handle multicast, */
+ 			    /* because it does not filter specific ethernet */
+ 			    /* multicast addresses, but just accepts all.   */
+ 				off_t multiaddr;
+ 				struct arpcom ac;
+ 				struct ether_multi enm;
+  
+ 				kread(ifnetfound, (char *)&ac, sizeof ac);
+ 				printf("%23s %s\n", "",
+ 					etherprint(&ac.ac_enaddr));
+ 				multiaddr = (off_t)ac.ac_multiaddrs;
+ 				while (multiaddr != 0) {
+ 					kread(multiaddr, (char *)&enm,
+ 							sizeof enm);
+ 					multiaddr = (off_t)enm.enm_next;
+ 					printf("%23s %s", "",
+ 						etherprint(&enm.enm_addrlo));
+ 					if (bcmp(&enm.enm_addrlo,
+ 						 &enm.enm_addrhi, 6) != 0)
+ 						printf(" to %s",
+ 						etherprint(&enm.enm_addrhi));
+ 					printf("\n");
+ 				}
+ 			}
+ 		}
  	}
  }
  
***************
*** 342,345 ****
--- 415,433 ----
  		goto banner;
  	goto loop;
  	/*NOTREACHED*/
+ }
+ 
+ /*               
+  * Return a printable string representation of an Ethernet address.
+  */                     
+ char *etherprint(enaddr)
+ 	char enaddr[6];
+ {
+ 	static char string[18];
+ 	unsigned char *en = (unsigned char *)enaddr;
+  
+ 	sprintf(string, "%02x:%02x:%02x:%02x:%02x:%02x",
+ 		en[0], en[1], en[2], en[3], en[4], en[5] );
+ 	string[17] = '\0'; 
+ 	return(string);
  }
