📄 getipnode.c
字号:
break; case AF_INET6: if (*have_v6 == 0) { memcpy(&in6, &((struct sockaddr_in6 *) &lifreq.lifr_addr)->sin6_addr, sizeof(in6)); if (memcmp(&in6, &in6addr_any, sizeof(in6)) == 0) break; n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq); if (n < 0) break; if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v6 = 1; } break; } } if (buf != NULL) free(buf); close(s); return (0); err_ret: if (buf != NULL) free(buf); if (s != -1) close(s); return (-1);}#endifstatic intscan_interfaces(int *have_v4, int *have_v6) {#if !defined(SIOCGIFCONF) || !defined(SIOCGIFADDR) *have_v4 = *have_v6 = 1; return (0);#else struct ifconf ifc; union { char _pad[256]; /* leave space for IPv6 addresses */ struct ifreq ifreq; } u; struct in_addr in4; struct in6_addr in6; char *buf = NULL, *cp, *cplim; static unsigned int bufsiz = 4095; int s, n; size_t cpsize;#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) /* * Try to scan the interfaces using IPv6 ioctls(). */ if (!scan_interfaces6(have_v4, have_v6)) return (0);#endif /* * Set to zero. Used as loop terminators below. */ *have_v4 = *have_v6 = 0; /* * Get interface list from system. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) goto err_ret; /* * Grow buffer until large enough to contain all interface * descriptions. */ for (;;) { buf = malloc(bufsiz); if (buf == NULL) goto err_ret; ifc.ifc_len = bufsiz; ifc.ifc_buf = buf;#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF /* * This is a fix for IRIX OS in which the call to ioctl with * the flag SIOCGIFCONF may not return an entry for all the * interfaces like most flavors of Unix. */ if (emul_ioctl(&ifc) >= 0) break;#else if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.ifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (ifc.ifc_len + 2 * sizeof(u.ifreq) < bufsiz) break; }#endif if ((n == -1) && errno != EINVAL) goto err_ret; if (bufsiz > 1000000) goto err_ret; free(buf); bufsiz += 4096; } /* * Parse system's interface list. */ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */ for (cp = buf; (*have_v4 == 0 || *have_v6 == 0) && cp < cplim; cp += cpsize) { memcpy(&u.ifreq, cp, sizeof(u.ifreq));#ifdef LWRES_PLATFORM_HAVESALEN#ifdef FIX_ZERO_SA_LEN if (u.ifreq.ifr_addr.sa_len == 0) u.ifreq.ifr_addr.sa_len = 16;#endif#ifdef HAVE_MINIMUM_IFREQ cpsize = sizeof(u.ifreq); if (u.ifreq.ifr_addr.sa_len > sizeof(struct sockaddr)) cpsize += (int)u.ifreq.ifr_addr.sa_len - (int)(sizeof(struct sockaddr));#else cpsize = sizeof(u.ifreq.ifr_name) + u.ifreq.ifr_addr.sa_len;#endif /* HAVE_MINIMUM_IFREQ */ if (cpsize > sizeof(u.ifreq) && cpsize <= sizeof(u)) memcpy(&u.ifreq, cp, cpsize);#elif defined SIOCGIFCONF_ADDR cpsize = sizeof(u.ifreq);#else cpsize = sizeof(u.ifreq.ifr_name); /* XXX maybe this should be a hard error? */ if (ioctl(s, SIOCGIFADDR, (char *)&u.ifreq) < 0) continue;#endif switch (u.ifreq.ifr_addr.sa_family) { case AF_INET: if (*have_v4 == 0) { memcpy(&in4, &((struct sockaddr_in *) &u.ifreq.ifr_addr)->sin_addr, sizeof(in4)); if (in4.s_addr == INADDR_ANY) break; n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq); if (n < 0) break; if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v4 = 1; } break; case AF_INET6: if (*have_v6 == 0) { memcpy(&in6, &((struct sockaddr_in6 *) &u.ifreq.ifr_addr)->sin6_addr, sizeof(in6)); if (memcmp(&in6, &in6addr_any, sizeof(in6)) == 0) break; n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq); if (n < 0) break; if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v6 = 1; } break; } } if (buf != NULL) free(buf); close(s); return (0); err_ret: if (buf != NULL) free(buf); if (s != -1) close(s); return (-1);#endif}static struct hostent *copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num){ struct hostent *he = NULL; int addresses = 1; /* NULL terminator */ int names = 1; /* NULL terminator */ int len = 0; char **cpp, **npp; /* * Work out array sizes. */ if (he1 != NULL) { cpp = he1->h_addr_list; while (*cpp != NULL) { addresses++; cpp++; } cpp = he1->h_aliases; while (*cpp != NULL) { names++; cpp++; } } if (he2 != NULL) { cpp = he2->h_addr_list; while (*cpp != NULL) { addresses++; cpp++; } if (he1 == NULL) { cpp = he2->h_aliases; while (*cpp != NULL) { names++; cpp++; } } } if (addresses == 1) { *error_num = NO_ADDRESS; return (NULL); } he = malloc(sizeof(*he)); if (he == NULL) goto no_recovery; he->h_addr_list = malloc(sizeof(char *) * (addresses)); if (he->h_addr_list == NULL) goto cleanup0; memset(he->h_addr_list, 0, sizeof(char *) * (addresses)); /* * Copy addresses. */ npp = he->h_addr_list; if (he1 != NULL) { cpp = he1->h_addr_list; while (*cpp != NULL) { *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ); if (*npp == NULL) goto cleanup1; /* * Convert to mapped if required. */ if (af == AF_INET6 && he1->h_addrtype == AF_INET) { memcpy(*npp, in6addr_mapped, sizeof(in6addr_mapped)); memcpy(*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ); } else { memcpy(*npp, *cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ); } cpp++; npp++; } } if (he2 != NULL) { cpp = he2->h_addr_list; while (*cpp != NULL) { *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ); if (*npp == NULL) goto cleanup1; /* * Convert to mapped if required. */ if (af == AF_INET6 && he2->h_addrtype == AF_INET) { memcpy(*npp, in6addr_mapped, sizeof(in6addr_mapped)); memcpy(*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ); } else { memcpy(*npp, *cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ); } cpp++; npp++; } } he->h_aliases = malloc(sizeof(char *) * (names)); if (he->h_aliases == NULL) goto cleanup1; memset(he->h_aliases, 0, sizeof(char *) * (names)); /* * Copy aliases. */ npp = he->h_aliases; cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases; while (*cpp != NULL) { len = strlen (*cpp) + 1; *npp = malloc(len); if (*npp == NULL) goto cleanup2; strcpy(*npp, *cpp); npp++; cpp++; } /* * Copy hostname. */ he->h_name = malloc(strlen((he1 != NULL) ? he1->h_name : he2->h_name) + 1); if (he->h_name == NULL) goto cleanup2; strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name); /* * Set address type and length. */ he->h_addrtype = af; he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ; return (he); cleanup2: cpp = he->h_aliases; while (*cpp != NULL) { free(*cpp); cpp++; } free(he->h_aliases); cleanup1: cpp = he->h_addr_list; while (*cpp != NULL) { free(*cpp); *cpp = NULL; cpp++; } free(he->h_addr_list); cleanup0: free(he); no_recovery: *error_num = NO_RECOVERY; return (NULL);}static struct hostent *hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) { struct hostent *he; int i; he = malloc(sizeof(*he)); if (he == NULL) goto cleanup; memset(he, 0, sizeof(*he)); /* * Set family and length. */ he->h_addrtype = af; switch (af) { case AF_INET: he->h_length = INADDRSZ; break; case AF_INET6: he->h_length = IN6ADDRSZ; break; default: INSIST(0); } /* * Copy name. */ he->h_name = strdup(addr->realname); if (he->h_name == NULL) goto cleanup; /* * Copy aliases. */ he->h_aliases = malloc(sizeof(char *) * (addr->naliases + 1)); if (he->h_aliases == NULL) goto cleanup; for (i = 0; i < addr->naliases; i++) { he->h_aliases[i] = strdup(addr->aliases[i]); if (he->h_aliases[i] == NULL) goto cleanup; } he->h_aliases[i] = NULL; /* * Copy address. */ he->h_addr_list = malloc(sizeof(char *) * 2); if (he->h_addr_list == NULL) goto cleanup; he->h_addr_list[0] = malloc(he->h_length); if (he->h_addr_list[0] == NULL) goto cleanup; memcpy(he->h_addr_list[0], src, he->h_length); he->h_addr_list[1] = NULL; return (he); cleanup: if (he != NULL && he->h_addr_list != NULL) { for (i = 0; he->h_addr_list[i] != NULL; i++) free(he->h_addr_list[i]); free(he->h_addr_list); } if (he != NULL && he->h_aliases != NULL) { for (i = 0; he->h_aliases[i] != NULL; i++) free(he->h_aliases[i]); free(he->h_aliases); } if (he != NULL && he->h_name != NULL) free(he->h_name); if (he != NULL) free(he); return (NULL);}static struct hostent *hostfromname(lwres_gabnresponse_t *name, int af) { struct hostent *he; int i; lwres_addr_t *addr; he = malloc(sizeof(*he)); if (he == NULL) goto cleanup; memset(he, 0, sizeof(*he)); /* * Set family and length. */ he->h_addrtype = af; switch (af) { case AF_INET: he->h_length = INADDRSZ; break; case AF_INET6: he->h_length = IN6ADDRSZ; break; default: INSIST(0); } /* * Copy name. */ he->h_name = strdup(name->realname); if (he->h_name == NULL) goto cleanup; /* * Copy aliases. */ he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1)); for (i = 0; i < name->naliases; i++) { he->h_aliases[i] = strdup(name->aliases[i]); if (he->h_aliases[i] == NULL) goto cleanup; } he->h_aliases[i] = NULL; /* * Copy addresses. */ he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1)); addr = LWRES_LIST_HEAD(name->addrs); i = 0; while (addr != NULL) { he->h_addr_list[i] = malloc(he->h_length); if (he->h_addr_list[i] == NULL) goto cleanup; memcpy(he->h_addr_list[i], addr->address, he->h_length); addr = LWRES_LIST_NEXT(addr, link); i++; } he->h_addr_list[i] = NULL; return (he); cleanup: if (he != NULL && he->h_addr_list != NULL) { for (i = 0; he->h_addr_list[i] != NULL; i++) free(he->h_addr_list[i]); free(he->h_addr_list); } if (he != NULL && he->h_aliases != NULL) { for (i = 0; he->h_aliases[i] != NULL; i++) free(he->h_aliases[i]); free(he->h_aliases); } if (he != NULL && he->h_name != NULL) free(he->h_name); if (he != NULL) free(he); return (NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -