- const char *hn,
- struct hostent *result,
- char *buffer,
- size_t buflen,
- int *errnop,
- int *h_errnop) {
-
- size_t l, idx;
- char *r_addr, *r_name, *r_aliases, *r_addr_list;
-
- l = strlen(hn);
- if (buflen < l+1+sizeof(char*)+4+sizeof(char*)*2) {
- *errnop = ENOMEM;
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_TRYAGAIN;
- }
-
- r_name = buffer;
- strcpy(buffer, hn);
-
- idx = l+1;
-
- *(char**) (buffer + idx) = NULL;
- r_aliases = buffer + idx;
- idx += sizeof(char*);
-
- r_addr = buffer + idx;
- *(uint32_t*) &buffer[idx] = LOCALADDRESS;
- idx += 4;
-
- r_addr_list = buffer + idx;
- * (char**) (buffer + idx) = r_addr;
- * (((char**) (buffer + idx)) +1) = NULL;
-
- result->h_name = r_name;
- result->h_aliases = (char**) r_aliases;
- result->h_addrtype = AF_INET;
- result->h_length = 4;
- result->h_addr_list = (char**) r_addr_list;
-
- return NSS_STATUS_SUCCESS;
+ const char *hn,
+ int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp,
+ char **canonp) {
+
+ size_t l, idx, ms;
+ char *r_addr, *r_name, *r_aliases, *r_addr_list;
+ size_t alen;
+
+ alen = af == AF_INET ? 4 : 16;
+
+ l = strlen(hn);
+ ms = ALIGN(l+1)+sizeof(char*)+ALIGN(alen)+sizeof(char*)*2;
+ if (buflen < ms) {
+ *errnop = ENOMEM;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ /* First, fill in hostname */
+ r_name = buffer;
+ memcpy(r_name, hn, l+1);
+ idx = ALIGN(l+1);
+
+ /* Second, create aliases array */
+ r_aliases = buffer + idx;
+ *(char**) r_aliases = NULL;
+ idx += sizeof(char*);
+
+ /* Third, add address */
+ r_addr = buffer + idx;
+ if (af == AF_INET)
+ *(uint32_t*) r_addr = LOCALADDRESS_IPV4;
+ else
+ memcpy(r_addr, LOCALADDRESS_IPV6, 16);
+ idx += ALIGN(alen);
+
+ /* Fourth, add address pointer array */
+ r_addr_list = buffer + idx;
+ ((char**) r_addr_list)[0] = r_addr;
+ ((char**) r_addr_list)[1] = NULL;
+ idx += sizeof(char*)*2;
+
+ /* Verify the size matches */
+ assert(idx == ms);
+
+ result->h_name = r_name;
+ result->h_aliases = (char**) r_aliases;
+ result->h_addrtype = af;
+ result->h_length = alen;
+ result->h_addr_list = (char**) r_addr_list;
+
+ if (ttlp)
+ *ttlp = 0;
+
+ if (canonp)
+ *canonp = r_name;
+
+ return NSS_STATUS_SUCCESS;