UnixOperatingSystem.st
changeset 15508 38541f2887de
parent 15492 626feb0ef3a5
child 15513 17c13e65f96a
equal deleted inserted replaced
15507:48222edbd770 15508:38541f2887de
  7036 
  7036 
  7037     "Created: 23.12.1995 / 14:19:20 / cg"
  7037     "Created: 23.12.1995 / 14:19:20 / cg"
  7038 !
  7038 !
  7039 
  7039 
  7040 getNetworkAddressInfo
  7040 getNetworkAddressInfo
  7041     "return a dictionary filled with
  7041     "return a Dictionary of network interface information. 
  7042 	key -> name of interface
  7042         key -> name of interface
  7043 	value -> the socket adress of the interface
  7043         value -> a Set of network address 
  7044      for each interface"
  7044                 information for the interface - a dictionaries containing the 
       
  7045                 information about the configuration of each interface in the system. 
       
  7046                 The dictionary keys are:
       
  7047                     #address
       
  7048                     #netmask
       
  7049                     #flags
       
  7050                     #destAddress"
  7045 
  7051 
  7046     |returnArray addressArray nameArray noOfIf retDictionary error retIndex|
  7052     |returnArray addressArray nameArray noOfIf retDictionary error retIndex|
  7047 
  7053 
  7048     noOfIf := 0.
  7054     noOfIf := 0.
  7049 
  7055 
  7059     int n_ifa = 0;
  7065     int n_ifa = 0;
  7060     int retI = 0;
  7066     int retI = 0;
  7061     OBJ t;
  7067     OBJ t;
  7062 
  7068 
  7063     if (getifaddrs(&ifap) < 0) {
  7069     if (getifaddrs(&ifap) < 0) {
  7064 	error = __MKSTRING("getifaddrs() failed");
  7070         error = __MKSTRING("getifaddrs() failed");
  7065 	goto out;
  7071         goto out;
  7066     }
  7072     }
  7067 
  7073 
  7068     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) n_ifa++;
  7074     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) n_ifa++;
  7069 
  7075 
  7070     returnArray = __ARRAY_NEW_INT(n_ifa*5);
  7076     returnArray = __ARRAY_NEW_INT(n_ifa*5);
  7071 
  7077 
  7072     if (returnArray == nil) {
  7078     if (returnArray == nil) {
  7073 	/* Creating a string wouldn't work here */
  7079         /* Creating a string wouldn't work here */
  7074 	error = @symbol(allocationFailure);
  7080         error = @symbol(allocationFailure);
  7075 	goto bad;
  7081         goto bad;
  7076     }
  7082     }
  7077 
  7083 
  7078     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) {
  7084     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) {
  7079 	int family, len;
  7085         int family, len;
  7080 
  7086 
  7081 	if (ifaLoop->ifa_addr == 0)
  7087         if (ifaLoop->ifa_addr == 0)
  7082 	       continue;
  7088                continue;
  7083 	family = ifaLoop->ifa_addr->sa_family;
  7089         family = ifaLoop->ifa_addr->sa_family;
  7084 	switch (family) {
  7090         switch (family) {
  7085 	case AF_INET:
  7091         case AF_INET:
  7086 	    len = sizeof(struct sockaddr_in);
  7092             len = sizeof(struct sockaddr_in);
  7087 	    break;
  7093             break;
  7088 	case AF_INET6:
  7094         case AF_INET6:
  7089 	    len = sizeof(struct sockaddr_in6);
  7095             len = sizeof(struct sockaddr_in6);
  7090 	    break;
  7096             break;
  7091 #if 0
  7097 #if 0
  7092 	case AF_PACKET:
  7098         case AF_PACKET:
  7093 	    len = sizeof(sockaddr_ll);
  7099             len = sizeof(sockaddr_ll);
  7094 	    break;
  7100             break;
  7095 #endif
  7101 #endif
  7096 	default:
  7102         default:
  7097 	    /* skip */
  7103             /* skip */
  7098 	    continue;
  7104             continue;
  7099 	};
  7105         };
  7100 	t = __MKSTRING(ifaLoop->ifa_name);
  7106         t = __MKSTRING(ifaLoop->ifa_name);
  7101 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7107         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7102 	t = __MKUINT(ifaLoop->ifa_flags);
  7108         t = __MKUINT(ifaLoop->ifa_flags);
  7103 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7109         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7104 	t = __MKBYTEARRAY((char *)ifaLoop->ifa_addr, len);
  7110         t = __MKBYTEARRAY((char *)ifaLoop->ifa_addr, len);
  7105 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7111         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7106 	if (ifaLoop->ifa_netmask != 0) {
  7112         if (ifaLoop->ifa_netmask != 0) {
  7107 	    t = __MKBYTEARRAY((char *)ifaLoop->ifa_netmask, len);
  7113             t = __MKBYTEARRAY((char *)ifaLoop->ifa_netmask, len);
  7108 	    __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7114             __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7109 	}
  7115         }
  7110 	retI++;
  7116         retI++;
  7111 	if (ifaLoop->ifa_dstaddr != 0) {
  7117         if (ifaLoop->ifa_dstaddr != 0) {
  7112 	    t = __MKBYTEARRAY((char *)ifaLoop->ifa_dstaddr, len);
  7118             t = __MKBYTEARRAY((char *)ifaLoop->ifa_dstaddr, len);
  7113 	    __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7119             __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7114 	}
  7120         }
  7115 	retI++;
  7121         retI++;
  7116     }
  7122     }
  7117 
  7123 
  7118     noOfIf = __mkSmallInteger(n_ifa);
  7124     noOfIf = __mkSmallInteger(n_ifa);
  7119 
  7125 
  7120 bad:
  7126 bad:
  7135     ** Open an INET socket
  7141     ** Open an INET socket
  7136     */
  7142     */
  7137 
  7143 
  7138     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7144     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7139     if (afinet_socket < 0) {
  7145     if (afinet_socket < 0) {
  7140 	goto bad;
  7146         goto bad;
  7141     }
  7147     }
  7142 
  7148 
  7143     /*
  7149     /*
  7144     ** Get the list of network interfaces
  7150     ** Get the list of network interfaces
  7145     */
  7151     */
  7146 
  7152 
  7147     ifc.ifc_len = sizeof (buf);
  7153     ifc.ifc_len = sizeof (buf);
  7148     ifc.ifc_buf = (caddr_t) buf;
  7154     ifc.ifc_buf = (caddr_t) buf;
  7149 
  7155 
  7150     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7156     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7151 	close(afinet_socket);
  7157         close(afinet_socket);
  7152 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7158         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7153 	goto bad;
  7159         goto bad;
  7154     }
  7160     }
  7155 
  7161 
  7156     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7162     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7157 
  7163 
  7158     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7164     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7159     addressArray = __ARRAY_NEW_INT(n_ifs);
  7165     addressArray = __ARRAY_NEW_INT(n_ifs);
  7160 
  7166 
  7161     if (nameArray == nil || addressArray == nil) {
  7167     if (nameArray == nil || addressArray == nil) {
  7162 	/* Creating a string wouldn/t work here */
  7168         /* Creating a string wouldn/t work here */
  7163 	error = @symbol(allocationFailure);
  7169         error = @symbol(allocationFailure);
  7164 	goto bad;
  7170         goto bad;
  7165     }
  7171     }
  7166 
  7172 
  7167     /*
  7173     /*
  7168     ** Iterate of the list of the system's netif. Find all
  7174     ** Iterate of the list of the system's netif. Find all
  7169     ** active interfaces and their ethernet addresses
  7175     ** active interfaces and their ethernet addresses
  7170     */
  7176     */
  7171     countOfIf = 0;
  7177     countOfIf = 0;
  7172 
  7178 
  7173     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++, ifr++) {
  7179     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++, ifr++) {
  7174 	/*
  7180         /*
  7175 	** Get address for this interface
  7181         ** Get address for this interface
  7176 	*/
  7182         */
  7177 	memset (&ifreq, 0, sizeof(ifreq));
  7183         memset (&ifreq, 0, sizeof(ifreq));
  7178 	memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
  7184         memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
  7179 	if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7185         if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7180 	    t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7186             t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7181 	    __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7187             __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7182 	    t = __MKSTRING(&ifreq.ifr_name);
  7188             t = __MKSTRING(&ifreq.ifr_name);
  7183 	    __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7189             __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7184 	    countOfIf++;
  7190             countOfIf++;
  7185 	} else {
  7191         } else {
  7186 	    fprintf(stderr, "SIOCGIFADDR failed: %s\n", errno);
  7192             fprintf(stderr, "SIOCGIFADDR failed: %s\n", errno);
  7187 	}
  7193         }
  7188 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7194         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7189     }
  7195     }
  7190 
  7196 
  7191     noOfIf = __mkSmallInteger(countOfIf);
  7197     noOfIf = __mkSmallInteger(countOfIf);
  7192 bad:
  7198 bad:
  7193     if (afinet_socket >= 0)
  7199     if (afinet_socket >= 0)
  7194 	close(afinet_socket);
  7200         close(afinet_socket);
  7195 #else
  7201 #else
  7196     error = @symbol(notSupported);
  7202     error = @symbol(notSupported);
  7197 #endif /* defined(SIOCGIFADDR) */
  7203 #endif /* defined(SIOCGIFADDR) */
  7198 out:;
  7204 out:;
  7199 %}.
  7205 %}.
  7200 
  7206 
  7201     retDictionary := Dictionary new:noOfIf.
  7207     retDictionary := Dictionary new:noOfIf.
  7202     error notNil ifTrue:[
  7208     error notNil ifTrue:[
  7203 	self primitiveFailed:error.
  7209         self primitiveFailed:error.
  7204 	"return empty dictionary if proceeding from error"
  7210         "return empty dictionary if proceeding from error"
  7205 	^  retDictionary.
  7211         ^  retDictionary.
  7206     ].
  7212     ].
  7207 
  7213 
  7208     retIndex := 1.
  7214     retIndex := 1.
  7209 
  7215 
  7210     1 to:noOfIf do:[:cnt|
  7216     1 to:noOfIf do:[:cnt|
  7211 	|name addressBytes set dict|
  7217         |name addressBytes set dict|
  7212 
  7218 
  7213 	name := returnArray at:retIndex.
  7219         name := returnArray at:retIndex.
  7214 	addressBytes := returnArray at:retIndex+2.
  7220         addressBytes := returnArray at:retIndex+2.
  7215 
  7221 
  7216 	addressBytes notNil ifTrue:[
  7222         addressBytes notNil ifTrue:[
  7217 	    set := retDictionary at:name ifAbsentPut:[Set new].
  7223             set := retDictionary at:name ifAbsentPut:[Set new].
  7218 	    dict := Dictionary new:5.
  7224             dict := Dictionary new:5.
  7219 	    dict at:#flags put:(returnArray at:retIndex+1).
  7225             dict at:#flags put:(returnArray at:retIndex+1).
  7220 	    dict at:#address put:(SocketAddress fromBytes:addressBytes).
  7226             dict at:#address put:(SocketAddress fromBytes:addressBytes).
  7221 	    addressBytes := returnArray at:retIndex+3.
  7227             addressBytes := returnArray at:retIndex+3.
  7222 	    addressBytes notNil ifTrue:[
  7228             addressBytes notNil ifTrue:[
  7223 		dict at:#netMask put:(SocketAddress fromBytes:addressBytes).
  7229                 dict at:#netMask put:(SocketAddress fromBytes:addressBytes).
  7224 	    ].
  7230             ].
  7225 	    addressBytes := returnArray at:retIndex+4.
  7231             addressBytes := returnArray at:retIndex+4.
  7226 	    addressBytes notNil ifTrue:[
  7232             addressBytes notNil ifTrue:[
  7227 		dict at:#destAddress put:(SocketAddress fromBytes:addressBytes).
  7233                 dict at:#destAddress put:(SocketAddress fromBytes:addressBytes).
  7228 	    ].
  7234             ].
  7229 	    set add:dict.
  7235             set add:dict.
  7230 	].
  7236         ].
  7231 	retIndex := retIndex + 5.
  7237         retIndex := retIndex + 5.
  7232     ].
  7238     ].
  7233 
  7239 
  7234     ^ retDictionary
  7240     ^ retDictionary
  7235 
  7241 
  7236     "
  7242     "
 13634 ! !
 13640 ! !
 13635 
 13641 
 13636 !UnixOperatingSystem class methodsFor:'documentation'!
 13642 !UnixOperatingSystem class methodsFor:'documentation'!
 13637 
 13643 
 13638 version
 13644 version
 13639     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.329 2013-07-08 19:27:29 stefan Exp $'
 13645     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.330 2013-07-10 08:23:04 stefan Exp $'
 13640 !
 13646 !
 13641 
 13647 
 13642 version_CVS
 13648 version_CVS
 13643     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.329 2013-07-08 19:27:29 stefan Exp $'
 13649     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.330 2013-07-10 08:23:04 stefan Exp $'
 13644 ! !
 13650 ! !
 13645 
 13651 
 13646 
 13652 
 13647 UnixOperatingSystem initialize!
 13653 UnixOperatingSystem initialize!
 13648 UnixOperatingSystem::FileDescriptorHandle initialize!
 13654 UnixOperatingSystem::FileDescriptorHandle initialize!