データ構造 | |
struct | afd |
struct | sockinet |
関数 | |
int | getnameinfo (struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) const |
変数 | |
static struct afd | afdl [] |
int getnameinfo | ( | struct sockaddr * | sa, | |
size_t | salen, | |||
char * | host, | |||
size_t | hostlen, | |||
char * | serv, | |||
size_t | servlen, | |||
int | flags | |||
) | const |
getnameinfo.c の 75 行で定義されています。
参照先 afd::a_addrlen・afd::a_af・afd::a_off・afd::a_socklen・afdl・freehostent()・inet_ntop()・snprintf().
参照元 client_addr()・lookup_name().
00083 { 00084 extern int h_errno; 00085 struct afd *afd; 00086 struct servent *sp; 00087 struct hostent *hp; 00088 u_short port; 00089 int family, i; 00090 char *addr, *p; 00091 u_long v4a; 00092 #ifdef INET6 00093 u_char pfx; 00094 #endif 00095 int h_error; 00096 char numserv[512]; 00097 char numaddr[512]; 00098 00099 if (sa == NULL) 00100 return ENI_NOSOCKET; 00101 00102 #ifdef HAVE_SOCKADDR_LEN 00103 if (sa->sa_len != salen) return ENI_SALEN; 00104 #endif 00105 00106 family = sa->sa_family; 00107 for (i = 0; afdl[i].a_af; i++) 00108 if (afdl[i].a_af == family) { 00109 afd = &afdl[i]; 00110 goto found; 00111 } 00112 return ENI_FAMILY; 00113 00114 found: 00115 if (salen != afd->a_socklen) return ENI_SALEN; 00116 00117 port = ((struct sockinet *)sa)->si_port; /* network byte order */ 00118 addr = (char *)sa + afd->a_off; 00119 00120 if (serv == NULL || servlen == 0) { 00121 /* what we should do? */ 00122 } else if (flags & NI_NUMERICSERV) { 00123 snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); 00124 if (strlen(numserv) > servlen) 00125 return ENI_MEMORY; 00126 strcpy(serv, numserv); 00127 } else { 00128 sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); 00129 if (sp) { 00130 if (strlen(sp->s_name) > servlen) 00131 return ENI_MEMORY; 00132 strcpy(serv, sp->s_name); 00133 } else 00134 return ENI_NOSERVNAME; 00135 } 00136 00137 switch (sa->sa_family) { 00138 case AF_INET: 00139 v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; 00140 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 00141 flags |= NI_NUMERICHOST; 00142 v4a >>= IN_CLASSA_NSHIFT; 00143 if (v4a == 0 || v4a == IN_LOOPBACKNET) 00144 flags |= NI_NUMERICHOST; 00145 break; 00146 #ifdef INET6 00147 case AF_INET6: 00148 pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; 00149 if (pfx == 0 || pfx == 0xfe || pfx == 0xff) 00150 flags |= NI_NUMERICHOST; 00151 break; 00152 #endif 00153 } 00154 if (host == NULL || hostlen == 0) { 00155 /* what should we do? */ 00156 } else if (flags & NI_NUMERICHOST) { 00157 if (!inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))) 00158 return ENI_SYSTEM; 00159 if (strlen(numaddr) > hostlen) 00160 return ENI_MEMORY; 00161 strcpy(host, numaddr); 00162 } else { 00163 #ifdef INET6 00164 hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 00165 #else 00166 hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); 00167 h_error = h_errno; 00168 #endif 00169 00170 if (hp) { 00171 if (flags & NI_NOFQDN) { 00172 p = strchr(hp->h_name, '.'); 00173 if (p) *p = '\0'; 00174 } 00175 if (strlen(hp->h_name) > hostlen) { 00176 #ifdef INET6 00177 freehostent(hp); 00178 #endif 00179 return ENI_MEMORY; 00180 } 00181 strcpy(host, hp->h_name); 00182 #ifdef INET6 00183 freehostent(hp); 00184 #endif 00185 } else { 00186 if (flags & NI_NAMEREQD) 00187 return ENI_NOHOSTNAME; 00188 if (!inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))) 00189 return ENI_NOHOSTNAME; 00190 if (strlen(numaddr) > hostlen) 00191 return ENI_MEMORY; 00192 strcpy(host, numaddr); 00193 } 00194 } 00195 return SUCCESS; 00196 }