* Interpret an argument as a network address of some kind, * returning 1 if a host address, 0 if a network address. */
| 1249 | * returning 1 if a host address, 0 if a network address. |
| 1250 | */ |
| 1251 | static int |
| 1252 | getaddr(int idx, char *str, struct hostent **hpp, int nrflags) |
| 1253 | { |
| 1254 | struct sockaddr *sa; |
| 1255 | #if defined(INET) |
| 1256 | struct sockaddr_in *sin; |
| 1257 | struct hostent *hp; |
| 1258 | char *q; |
| 1259 | #elif defined(INET6) |
| 1260 | char *q; |
| 1261 | #endif |
| 1262 | |
| 1263 | if (idx < 0 || idx >= RTAX_MAX) |
| 1264 | usage("internal error"); |
| 1265 | if (af == 0) { |
| 1266 | #if defined(INET) |
| 1267 | af = AF_INET; |
| 1268 | aflen = sizeof(struct sockaddr_in); |
| 1269 | #elif defined(INET6) |
| 1270 | af = AF_INET6; |
| 1271 | aflen = sizeof(struct sockaddr_in6); |
| 1272 | #else |
| 1273 | af = AF_LINK; |
| 1274 | aflen = sizeof(struct sockaddr_dl); |
| 1275 | #endif |
| 1276 | } |
| 1277 | #ifndef INET |
| 1278 | hpp = NULL; |
| 1279 | #endif |
| 1280 | rtm_addrs |= (1 << idx); |
| 1281 | sa = (struct sockaddr *)&so[idx]; |
| 1282 | sa->sa_family = af; |
| 1283 | sa->sa_len = aflen; |
| 1284 | |
| 1285 | switch (idx) { |
| 1286 | case RTAX_GATEWAY: |
| 1287 | if (nrflags & F_INTERFACE) { |
| 1288 | struct ifaddrs *ifap, *ifa; |
| 1289 | struct sockaddr_dl *sdl0 = (struct sockaddr_dl *)(void *)sa; |
| 1290 | struct sockaddr_dl *sdl = NULL; |
| 1291 | |
| 1292 | if (getifaddrs(&ifap)) |
| 1293 | err(EX_OSERR, "getifaddrs"); |
| 1294 | |
| 1295 | for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { |
| 1296 | if (ifa->ifa_addr->sa_family != AF_LINK) |
| 1297 | continue; |
| 1298 | |
| 1299 | if (strcmp(str, ifa->ifa_name) != 0) |
| 1300 | continue; |
| 1301 | |
| 1302 | sdl = (struct sockaddr_dl *)(void *)ifa->ifa_addr; |
| 1303 | } |
| 1304 | /* If we found it, then use it */ |
| 1305 | if (sdl != NULL) { |
| 1306 | /* |
| 1307 | * Note that we need to copy before calling |
| 1308 | * freeifaddrs(). |
no test coverage detected