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 " |