/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
}
__private_extern__ si_item_t *
-cache_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+cache_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
{
si_item_t *item;
}
__private_extern__ si_item_t *
-cache_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+cache_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
{
si_item_t *item;
}
__private_extern__ si_item_t *
-cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *ignored, uint32_t *err)
{
/*
* Caching of getnameinfo(3) is not supported.
out->sim_wants_addrinfo = NULL;
out->sim_addrinfo = NULL;
- /* no nameinfo support */
out->sim_nameinfo = cache_nameinfo;
return out;
}
__private_extern__ si_item_t *
-ds_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+ds_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
{
static int proc = -1;
kvbuf_t *request;
}
__private_extern__ si_item_t *
-ds_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+ds_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
{
static int proc = -1;
kvbuf_t *request;
}
static si_list_t *
-ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *ignored, uint32_t *err)
{
static int proc = -1;
si_list_t *list, *out;
/* look up canonical name of numeric host */
if ((numerichost == 1) && (flags & AI_CANONNAME) && (node != NULL))
{
- item = si_host_byaddr(si, node, family, NULL);
+ item = si_host_byaddr(si, node, family, NULL, NULL);
if (item != NULL)
{
h = (struct hostent *)((uintptr_t)item + sizeof(si_item_t));
}
__private_extern__ si_item_t *
-file_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+file_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
{
si_item_t *item;
}
__private_extern__ si_item_t *
-file_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+file_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
{
si_item_t *item;
/*
- * Copyright (c) 1999-2009 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
{
static si_mod_t *search = NULL;
static OSSpinLock spin = OS_SPINLOCK_INIT;
-
+
if (search == NULL)
{
OSSpinLockLock(&spin);
sictx->cat = CATEGORY_USER;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_USER_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_USER_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_USER;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_USER_BYUID, NULL, NULL, (uint32_t)uid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_USER_BYUID, NULL, NULL, NULL, (uint32_t)uid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
setpassent(int ignored)
{
si_list_t *list;
-
+
#ifdef CALL_TRACE
fprintf(stderr, "-> %s\n", __func__);
#endif
-
+
list = LI_get_thread_list(CATEGORY_USER);
si_list_reset(list);
sictx->cat = CATEGORY_GROUP;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_GROUP_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_GROUP_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_GROUP;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_GROUP_BYGID, NULL, NULL, (uint32_t)gid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_GROUP_BYGID, NULL, NULL, NULL, (uint32_t)gid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
setgroupent(int ignored)
{
si_list_t *list;
-
+
#ifdef CALL_TRACE
fprintf(stderr, "-> %s\n", __func__);
#endif
-
+
list = LI_get_thread_list(CATEGORY_GROUP);
si_list_reset(list);
si_item_t *item;
si_grouplist_t *gl;
gid_t *groups;
-
+
#ifdef CALL_TRACE
fprintf(stderr, "-> %s %s %d\n", __func__, name, basegid);
#endif
-
+
if (name == NULL) return 0;
-
+
item = si_grouplist(si_search(), name);
LI_set_thread_item(CATEGORY_GROUPLIST, item);
if (item == NULL) return -1;
-
+
gl = (si_grouplist_t *)((uintptr_t)item + sizeof(si_item_t));
-
+
count = 0;
groups = NULL;
-
+
status = merge_gid(&groups, basegid, &count);
if (status != 0) return status;
-
+
status = merge_gid(&groups, gl->gl_basegid, &count);
if (status != 0) return status;
-
+
for (i = 0; i < gl->gl_count; i++)
{
g = (gid_t)*(gl->gl_gid[i]);
sictx->cat = CATEGORY_ALIAS;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
status = SI_STATUS_NO_ERROR;
item = NULL;
- if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, &status);
- else item = si_host_byname(si_search(), name, AF_INET, &status);
+ if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, NULL, &status);
+ else item = si_host_byname(si_search(), name, AF_INET, NULL, &status);
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
if (err != NULL) *err = status;
status = SI_STATUS_NO_ERROR;
item = NULL;
- if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, &status);
- else item = si_host_byname(si_search(), name, AF_INET, &status);
+ if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, NULL, &status);
+ else item = si_host_byname(si_search(), name, AF_INET, NULL, &status);
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
h_errno = status;
sictx->cat = CATEGORY_HOST;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, AF_INET, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, NULL, AF_INET, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
mach_port_t
#ifdef CALL_TRACE
fprintf(stderr, "<< %s\n", __func__);
#endif
-
+
msg = (mach_msg_header_t *)param;
si_async_handle_reply(msg);
}
gethostbyname_async_handleReply(void *param)
{
mach_msg_header_t *msg;
-
+
#ifdef CALL_TRACE
fprintf(stderr, "<< %s\n", __func__);
#endif
if (((af == AF_INET) && (inet_aton(name, &addr4) == 1)) || ((af == AF_INET6) && (inet_pton(af, name, &addr6) == 1)))
{
- item = si_ipnode_byname(search, name, (uint32_t)af, 0, &status);
+ item = si_ipnode_byname(search, name, (uint32_t)af, 0, NULL, &status);
}
else
{
- item = si_host_byname(search, name, (uint32_t)af, &status);
+ item = si_host_byname(search, name, (uint32_t)af, NULL, &status);
}
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
sictx->cat = CATEGORY_HOST;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, (uint32_t)af, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, NULL, (uint32_t)af, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
status = SI_STATUS_NO_ERROR;
- item = si_host_byaddr(si_search(), addr, (uint32_t)type, &status);
+ item = si_host_byaddr(si_search(), addr, (uint32_t)type, NULL, &status);
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
h_errno = status;
/* addr is not a C string - pass length in num3 */
addrlen = len;
- return si_async_call(si_search(), SI_CALL_HOST_BYADDR, addr, NULL, (uint32_t)type, 0, addrlen, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_HOST_BYADDR, addr, NULL, NULL, (uint32_t)type, 0, addrlen, 0, (void *)si_libinfo_general_callback, sictx);
}
mach_port_t
#ifdef CALL_TRACE
fprintf(stderr, "<< %s\n", __func__);
#endif
-
+
msg = (mach_msg_header_t *)param;
si_async_handle_reply(msg);
}
status = SI_STATUS_NO_ERROR;
- item = si_ipnode_byname(si_search(), name, family, flags, &status);
+ item = si_ipnode_byname(si_search(), name, family, flags, NULL, &status);
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
if (err != NULL) *err = status;
sictx->cat = CATEGORY_HOST;
sictx->key_offset = -1;
- return si_async_call(si_search(), SI_CALL_IPNODE_BYNAME, name, NULL, (uint32_t)family, (uint32_t)flags, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_IPNODE_BYNAME, name, NULL, NULL, (uint32_t)family, (uint32_t)flags, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
mach_port_t
family = AF_INET;
}
- item = si_host_byaddr(si_search(), src, family, (uint32_t *)err);
+ item = si_host_byaddr(si_search(), src, family, NULL, (uint32_t *)err);
if (item == NULL) return NULL;
return (struct hostent *)((uintptr_t)item + sizeof(si_item_t));
/* src is not a C string - pass length in num3 */
srclen = len;
- return si_async_call(si_search(), SI_CALL_HOST_BYADDR, src, NULL, (uint32_t)family, 0, srclen, 0, (void *)si_libinfo_ipnode_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_HOST_BYADDR, src, NULL, NULL, (uint32_t)family, 0, srclen, 0, (void *)si_libinfo_ipnode_callback, sictx);
}
mach_port_t
#ifdef CALL_TRACE
fprintf(stderr, "-- %s\n", __func__);
#endif
-
+
LI_set_thread_list(CATEGORY_HOST, NULL);
}
/* XXX to do? async ether_hostton */
-int ether_ntohost(char *name, const struct ether_addr *e)
+int
+ether_ntohost(char *name, const struct ether_addr *e)
{
si_item_t *item;
char *cname;
sictx->cat = CATEGORY_NETWORK;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_NETWORK;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR, NULL, NULL, net, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR, NULL, NULL, NULL, net, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
#ifdef CALL_TRACE
fprintf(stderr, "-- %s\n", __func__);
#endif
-
+
LI_set_thread_list(CATEGORY_NETWORK, NULL);
}
sictx->cat = CATEGORY_SERVICE;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME, name, proto, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME, name, proto, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_SERVICE;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT, NULL, proto, port, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT, NULL, proto, NULL, port, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
#ifdef CALL_TRACE
fprintf(stderr, "-- %s\n", __func__);
#endif
-
+
LI_set_thread_list(CATEGORY_SERVICE, NULL);
}
sictx->cat = CATEGORY_PROTOCOL;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_PROTOCOL;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER, NULL, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
#ifdef CALL_TRACE
fprintf(stderr, "-- %s\n", __func__);
#endif
-
+
LI_set_thread_list(CATEGORY_PROTOCOL, NULL);
}
sictx->cat = CATEGORY_RPC;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_RPC_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_RPC_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_RPC;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER, NULL, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
#ifdef CALL_TRACE
fprintf(stderr, "-- %s\n", __func__);
#endif
-
+
LI_set_thread_list(CATEGORY_RPC, NULL);
}
sictx->cat = CATEGORY_FS;
sictx->key_offset = 100;
- return si_async_call(si_search(), SI_CALL_FS_BYSPEC, spec, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_FS_BYSPEC, spec, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
sictx->cat = CATEGORY_FS;
sictx->key_offset = 200;
- return si_async_call(si_search(), SI_CALL_FS_BYFILE, file, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_FS_BYFILE, file, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
}
void
/* GETADDRINFO */
-int
-getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
+static int
+_getaddrinfo_internal(const char *nodename, const char *servname, const struct addrinfo *hints, const char *interface, struct addrinfo **res)
{
si_list_t *list;
uint32_t family, socktype, protocol, flags, status;
}
#ifdef CALL_TRACE
- fprintf(stderr, "-> %s %s %s %u %u %u 0x%08x\n", __func__, nodename, servname, family, socktype, protocol, flags);
+ fprintf(stderr, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__, nodename, servname, family, socktype, protocol, flags, (interface == NULL) ? "" : interface);
#endif
- list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, &status);
+ list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, interface, &status);
if ((status != SI_STATUS_NO_ERROR) || (list == NULL))
{
si_list_release(list);
return status;
}
+int
+getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
+{
+ return _getaddrinfo_internal(nodename, servname, hints, NULL, res);
+}
+
#ifdef CALL_TRACE
static char *
free(sictx);
}
+/* SPI */
mach_port_t
-getaddrinfo_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, si_addrinfo_async_callback callback, void *context)
+_getaddrinfo_interface_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, const char *interface, si_addrinfo_async_callback callback, void *context)
{
si_context_t *sictx;
uint32_t family, socktype, protocol, flags;
sictx->cat = CATEGORY_ADDRINFO;
sictx->key_offset = 0;
- return si_async_call(si_search(), SI_CALL_ADDRINFO, nodename, servname, family, socktype, protocol, flags, (void *)si_libinfo_addrinfo_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_ADDRINFO, nodename, servname, interface, family, socktype, protocol, flags, (void *)si_libinfo_addrinfo_callback, sictx);
+}
+
+mach_port_t
+getaddrinfo_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, si_addrinfo_async_callback callback, void *context)
+{
+ return _getaddrinfo_interface_async_call(nodename, servname, hints, NULL, callback, context);
}
int32_t
/* GETNAMEINFO */
-int
-getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
+static int
+_getnameinfo_interface_internal(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags, const char *interface)
{
si_item_t *item;
si_nameinfo_t *ni;
if (wantn == 0) flags |= NI_NUMERICHOST;
if (wants == 0) flags |= NI_NUMERICSERV;
- item = si_nameinfo(si_search(), sa, flags, &status);
+ item = si_nameinfo(si_search(), sa, flags, interface, &status);
if ((status != SI_STATUS_NO_ERROR) || (item == NULL))
{
si_item_release(item);
-
+
if (status == SI_STATUS_NO_ERROR) status = EAI_NONAME;
else if (status <= SI_STATUS_EAI_PLUS_100) status = EAI_FAIL;
else if (status >= SI_STATUS_ERRNO_PLUS_200) status = EAI_FAIL;
return 0;
}
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
+{
+ return _getnameinfo_interface_internal(sa, salen, node, nodelen, service, servicelen, flags, NULL);
+}
+
static void
si_libinfo_nameinfo_callback(si_item_t *item, uint32_t status, void *ctx)
{
free(sictx);
}
+/* SPI */
mach_port_t
-getnameinfo_async_call(const struct sockaddr *sa, size_t len, int flags, si_nameinfo_async_callback callback, void *context)
+_getnameinfo_interface_async_call(const struct sockaddr *sa, size_t len, int flags, const char *interface, si_nameinfo_async_callback callback, void *context)
{
si_context_t *sictx;
uint32_t salen;
/* sa is not a C string - pass length in num3 */
salen = len;
- return si_async_call(si_search(), SI_CALL_NAMEINFO, (const char *)sa, NULL, flags, 0, salen, 0, (void *)si_libinfo_nameinfo_callback, sictx);
+ return si_async_call(si_search(), SI_CALL_NAMEINFO, (const char *)sa, NULL, interface, flags, 0, salen, 0, (void *)si_libinfo_nameinfo_callback, sictx);
+}
+
+mach_port_t
+getnameinfo_async_call(const struct sockaddr *sa, size_t len, int flags, si_nameinfo_async_callback callback, void *context)
+{
+ return _getnameinfo_interface_async_call(sa, len, flags, NULL, callback, context);
}
int32_t
{
struct passwd *pw;
static char buf[16];
-
+
pw = getpwuid(uid);
if (pw != NULL) return pw->pw_name;
-
+
if (nouser) return NULL;
-
+
snprintf(buf, sizeof(buf), "%u", uid);
- return buf;
+ return buf;
}
char *
{
struct group *gr;
static char buf[16];
-
+
gr = getgrgid(gid);
if (gr != NULL) return gr->gr_name;
-
+
if (nogroup) return NULL;
-
+
snprintf(buf, sizeof(buf), "%u", gid);
- return buf;
+ return buf;
}
/* no longer supported */
#endif
return 0;
}
-
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
#include <time.h>
#include <unistd.h>
#include <asl.h>
DNSServiceRef _mdns_sdref;
DNSServiceRef _mdns_old_sdref;
-static int _mdns_query_mDNSResponder(const char *name, int class, int type,
- uint8_t *answer, uint32_t *anslen,
- mdns_reply_t *reply, uint32_t timeout);
+static int _mdns_query_mDNSResponder(const char *name, int class, int type, const char *interface,
+ uint8_t *answer, uint32_t *anslen,
+ mdns_reply_t *reply, uint32_t timeout);
static int _mdns_resolver_get_option(dns_resolver_t *resolver, const char* option);
static void _mdns_hostent_clear(mdns_hostent_t *h);
if (resolver->domain == NULL) return NULL;
domain = strdup(resolver->domain);
if (domain == NULL) return NULL;
-
+
// count dots
n = 0;
for (p = domain; *p != '\0'; p++) {
if (*p == '.') n++;
}
-
+
// trim trailing dots
for (p--; (p >= domain) && (*p == '.'); p--) {
*p = '\0';
n--;
}
-
+
// make sure the resulting string is not empty
if (p < domain) {
free(domain);
return NULL;
}
-
+
// dots are separators, so number of components is one larger
n++;
-
+
m = 0;
list = (char **)calloc(n+1, sizeof(char *));
if (list == NULL) return NULL;
// first item in list is domain itself
list[m++] = domain;
-
+
// include parent domains with at least LOCALDOMAINPARTS components
p = domain;
while (n > LOCALDOMAINPARTS) {
}
config->n_defaults = m;
// sort list by search order ascending
- qsort(config->defaults, config->n_defaults,
- sizeof(dns_resolver_t *), _mdns_compare_resolvers);
+ qsort(config->defaults, config->n_defaults, sizeof(dns_resolver_t *), _mdns_compare_resolvers);
}
#if 0
* Retain the mdns configuration.
*/
static mdns_config_t *
-_mdns_config_retain(mdns_config_t *config) {
+_mdns_config_retain(mdns_config_t *config)
+{
int32_t rc;
+
if (config == NULL) return NULL;
rc = OSAtomicIncrement32Barrier(&config->rc);
assert(rc > 1);
return config;
}
+
/* _mdns_config_release
* Releases the mdns configuration structure and
* frees the data if no references remain.
*/
static void
-_mdns_config_release(mdns_config_t *config) {
+_mdns_config_release(mdns_config_t *config)
+{
int32_t rc;
+
if (config == NULL) return;
rc = OSAtomicDecrement32Barrier(&config->rc);
assert(rc >= 0);
res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
}
+
if (_dns_config_token != -1) {
res = notify_check(_dns_config_token, &refresh);
if (res != NOTIFY_STATUS_OK) refresh = 1;
* of the default resolver's domains).
*/
static int
-_mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
{
int i, res = -1;
for (i = 0; i < config->n_defaults; ++i) {
dns_resolver_t *resolver = config->defaults[i];
char *qname;
-
- asprintf(&qname, "%s.%s", name,
- resolver->domain ? resolver->domain : "");
- res = _mdns_query_mDNSResponder(qname, class, type, buf, len, reply, resolver->timeout);
+
+ asprintf(&qname, "%s.%s", name, resolver->domain ? resolver->domain : "");
+ res = _mdns_query_mDNSResponder(qname, class, type, interface, buf, len, reply, resolver->timeout);
free(qname);
if (res == 0) break;
* additional domains).
*/
static int
-_mdns_query_absolute(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_query_absolute(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, uint32_t fqdn, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
{
int res = -1;
char *qname = (char *)name;
-
+
uint32_t timeout = _mdns_timeout_for_name(config, name);
if (fqdn == 0) asprintf(&qname, "%s.", name);
- res = _mdns_query_mDNSResponder(qname, class, type, buf, len, reply, timeout);
+ res = _mdns_query_mDNSResponder(qname, class, type, interface, buf, len, reply, timeout);
if (fqdn == 0) free(qname);
if (res != 0) _mdns_reply_clear(reply);
return res;
}
static int
-_mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint32_t recurse, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_search(const char *name, uint32_t class, uint32_t type, const char *interface, uint32_t fqdn, uint32_t recurse, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
{
int res = -1;
int i, n, ndots;
// NDOTS is the threshold for trying a qualified name "as is"
ndots = config->ndots;
if (ndots == 0) ndots = 1;
-
+
// count the dots, and remember position of the last one
n = 0;
dot = NULL;
// if the name has at least ndots, try first as an absolute query.
// FQDN and PTR queries are always absolute.
if (n >= ndots || fqdn == 1 || type == ns_t_ptr) {
- res = _mdns_query_absolute(config, name, class, type, fqdn, buf, len, reply);
+ res = _mdns_query_absolute(config, name, class, type, interface, fqdn, buf, len, reply);
if (res == 0) {
_mdns_config_release(config);
return res;
}
}
-
+
// stop if FQDN, PTR, or no recursion requested
if (fqdn == 1 || type == ns_t_ptr || recurse == 0) {
_mdns_config_release(config);
return -1;
}
-
+
// Qualify the name with each of the search domains looking for a match.
char **search = config->search_list;
if (search != NULL) {
for (i = 0; i < MAXDNSRCH && search[i] != NULL; ++i) {
char *qname;
asprintf(&qname, "%s.%s", name, search[i]);
- res = _mdns_search(qname, class, type, 0, 0, buf, len, reply);
+ res = _mdns_search(qname, class, type, interface, 0, 0, buf, len, reply);
free(qname);
if (res == 0) break;
}
// The name is not fully qualified and there is no search list.
// Try each default resolver, qualifying the name with that
// resolver's domain.
- res = _mdns_query_unqualified(config, name, class, type, buf, len, reply);
+ res = _mdns_query_unqualified(config, name, class, type, interface, buf, len, reply);
}
_mdns_config_release(config);
return res;
unsigned char b[4];
} ab;
char *p;
-
+
if (addr == NULL) return NULL;
-
+
memcpy(&(ab.a), addr, 4);
-
+
asprintf(&p, "%u.%u.%u.%u.in-addr.arpa.", ab.b[3], ab.b[2], ab.b[1], ab.b[0]);
return p;
}
char x[65], *p;
int i, j;
u_int8_t d, hi, lo;
-
+
if (addr == NULL) return NULL;
-
+
x[64] = '\0';
j = 63;
for (i = 0; i < 16; i++)
x[j--] = '.';
x[j--] = hexchar[lo];
}
-
+
asprintf(&p, "%sip6.arpa.", x);
return p;
return 0;
}
}
-
+
// add the alias and NULL terminate the list
h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count+2) * sizeof(char *));
if (h->host.h_aliases == NULL) {
free(h->host.h_aliases);
h->host.h_aliases = NULL;
h->alias_count = 0;
-
+
char **addrs = h->host.h_addr_list;
while (addrs && *addrs) {
free(*addrs++);
}
static si_item_t *
-_mdns_hostbyname(si_mod_t *si, const char *name, int af, uint32_t *err)
+_mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
{
uint32_t type;
mdns_hostent_t h;
si_item_t *out = NULL;
uint64_t bb;
int status;
-
+
if (err != NULL) *err = SI_STATUS_NO_ERROR;
if (name == NULL) {
}
h.host.h_addrtype = af;
- status = _mdns_search(name, ns_c_in, type, 0, 1, NULL, NULL, &reply);
+ status = _mdns_search(name, ns_c_in, type, interface, 0, 1, NULL, NULL, &reply);
if (status != 0 || h.addr_count == 0) {
_mdns_reply_clear(&reply);
if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
return NULL;
}
-
+
bb = reply.ttl + time(NULL);
switch (af) {
_mdns_reply_clear(&reply);
if (out == NULL && err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
-
+
return out;
}
static si_item_t *
-_mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+_mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
{
mdns_hostent_t h;
mdns_reply_t reply;
uint64_t bb;
int cat;
int status;
-
+
if (err != NULL) *err = SI_STATUS_NO_ERROR;
-
+
if (addr == NULL || si == NULL) {
if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
return NULL;
}
h.host.h_addrtype = af;
- status = _mdns_search(name, ns_c_in, ns_t_ptr, 0, 1, NULL, NULL, &reply);
+ status = _mdns_search(name, ns_c_in, ns_t_ptr, interface, 0, 1, NULL, NULL, &reply);
free(name);
if (status != 0) {
_mdns_reply_clear(&reply);
if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
return NULL;
- }
+ }
status = _mdns_hostent_append_addr(&h, addr, h.host.h_length);
if (status != 0) {
// embedded does not do parallel A/AAAA
#if !TARGET_OS_EMBEDDED
static si_list_t *
-_mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
int wantv4 = 1;
int wantv6 = 1;
if (family == AF_INET6) wantv4 = 0;
else if (family == AF_INET) wantv6 = 0;
else if (family != AF_UNSPEC) return NULL;
-
+
struct in_addr a4;
struct in6_addr a6;
mdns_hostent_t h4;
memset(&h4, 0, sizeof(h4));
memset(&h6, 0, sizeof(h6));
memset(&reply, 0, sizeof(reply));
-
+
h4.host.h_addrtype = AF_INET;
h4.host.h_length = 4;
h6.host.h_addrtype = AF_INET6;
h6.host.h_length = 16;
-
+
if (wantv4 && wantv6) {
type = 0;
reply.h4 = &h4;
p6 = &a6;
memcpy(p6, node, sizeof(a6));
}
- out = si_addrinfo_list(si, socktype, proto,
- p4, p6, port, 0, cname, cname);
+ out = si_addrinfo_list(si, socktype, proto, p4, p6, port, 0, cname, cname);
} else {
int res;
- res = _mdns_search(node, ns_c_in, type, 0, 1, NULL, NULL, &reply);
+ res = _mdns_search(node, ns_c_in, type, interface, 0, 1, NULL, NULL, &reply);
if (res == 0 && (h4.addr_count > 0 || h6.addr_count > 0)) {
out = si_addrinfo_list_from_hostent(si, socktype, proto,
- port, 0,
- (wantv4 ? &h4.host : NULL),
- (wantv6 ? &h6.host : NULL));
+ port, 0,
+ (wantv4 ? &h4.host : NULL),
+ (wantv6 ? &h6.host : NULL));
} else if (err != NULL) {
*err = SI_STATUS_EAI_NONAME;
}
#endif // !TARGET_OS_EMBEDDED
static si_list_t *
-_mdns_srv_byname(si_mod_t* si, const char *qname, uint32_t *err)
+_mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t *err)
{
si_list_t *out = NULL;
mdns_reply_t reply;
const uint64_t unused = 0;
if (err != NULL) *err = SI_STATUS_NO_ERROR;
-
+
memset(&reply, 0, sizeof(reply));
- res = _mdns_search(qname, ns_c_in, ns_t_srv, 0, 1, NULL, NULL, &reply);
+ res = _mdns_search(qname, ns_c_in, ns_t_srv, interface, 0, 1, NULL, NULL, &reply);
if (res == 0) {
srv = reply.srv;
while (srv) {
* We support dns_async_start / cancel / handle_reply using dns_item_call
*/
static si_item_t *
-_mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, uint32_t class, uint32_t type, uint32_t *err)
+_mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, const char *interface, uint32_t class, uint32_t type, uint32_t *err)
{
int res;
uint8_t buf[DNS_MAX_RECEIVE_SIZE];
mdns_hostent_t h6;
si_item_t *out;
int norecurse = 0;
-
+
if (err != NULL) *err = SI_STATUS_NO_ERROR;
switch (call) {
memset(&h4, 0, sizeof(h4));
memset(&h6, 0, sizeof(h6));
memset(&reply, 0, sizeof(reply));
-
+
h4.host.h_addrtype = AF_INET;
h4.host.h_length = 4;
h6.host.h_addrtype = AF_INET6;
h6.host.h_length = 16;
reply.h4 = &h4;
reply.h6 = &h6;
-
- res = _mdns_search(name, class, type, norecurse, 1, buf, &len, &reply);
+
+ res = _mdns_search(name, class, type, interface, norecurse, 1, buf, &len, &reply);
if (res != 0 || len <= 0 || len > DNS_MAX_RECEIVE_SIZE) {
_mdns_reply_clear(&reply);
if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
return NULL;
}
-
+
struct sockaddr_in6 from;
uint32_t fromlen = sizeof(from);
memset(&from, 0, fromlen);
static void
_mdns_close(si_mod_t *si)
{
- if (_dns_config_token != -1) notify_cancel(_dns_config_token);
+ if (_dns_config_token != -1) notify_cancel(_dns_config_token);
//_mdns_dir_token;
}
free(outname);
return NULL;
}
-
+
out->name = outname;
out->vers = 1;
out->refcount = 1;
out->private = NULL;
-
+
out->sim_close = _mdns_close;
out->sim_is_valid = _mdns_is_valid;
out->sim_host_byname = _mdns_hostbyname;
out->sim_addrinfo = _mdns_addrinfo;
#endif
out->sim_srv_byname = _mdns_srv_byname;
-
+
int res;
-
+
res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
uint32_t len;
uint32_t domainlen = 0;
char *domain = NULL;
-
+
// i: index into input data
// j: index into output string
while (datalen-- > 0) {
if (j > 0) {
domain[j++] = datalen ? '.' : '\0';
}
-
+
while ((len-- > 0) && (datalen--)) {
if (data[i] == '.') {
// special case: escape the '.' with a '\'
}
}
domain[j] = '\0';
-
+
return domain;
}
_is_rev_link_local(const char *name)
{
int len, i;
-
+
if (name == NULL) return 0;
-
+
len = strlen(name);
if (len == 0) return 0;
-
+
/* check for trailing '.' */
if (name[len - 1] == '.') len--;
-
+
if (len != IPv6_REVERSE_LEN) return 0;
-
+
i = IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR;
if ((name[i] != '8') && (name[i] != '9') && (name[i] != 'A') && (name[i] != 'a') && (name[i] != 'B') && (name[i] != 'b')) return 0;
-
+
i = IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR + 1;
if (strncasecmp(name + i, ".e.f.ip6.arpa", 13)) return 0;
-
+
for (i = 0; i < IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR; i += 2)
{
if (name[i] < '0') return 0;
if (name[i] > 'f') return 0;
if (name[i + 1] != '.') return 0;
}
-
+
return 1;
}
/* _mdns_ipv6_extract_scope_id
* If the input string is a link local IPv6 address with an encoded scope id,
- * the scope id is extracted to the "iface" parameter and a new string is
- * returned with it removed.
+ * the scope id is extracted and a new string is constructed with the scope id removed.
*/
static char *
-_mdns_ipv6_extract_scope_id(const char *name, uint32_t *outscope)
+_mdns_ipv6_extract_scope_id(const char *name, uint32_t *out_ifnum)
{
char *qname = NULL;
uint16_t nibble;
+ uint32_t iface;
int i;
-
- if (outscope) *outscope = 0;
-
- if (name && _is_rev_link_local(name)) {
- uint32_t iface;
-
+
+ if (out_ifnum != NULL) *out_ifnum = 0;
+
+ /* examine the address, extract the scope id if present */
+ if ((name != NULL) && (_is_rev_link_local(name)))
+ {
/* _is_rev_link_local rejects chars > 127 so it's safe to index into hexval */
i = IPv6_REVERSE_LINK_LOCAL_SCOPE_ID_LOW;
nibble = hexval[(uint32_t)name[i]];
iface = nibble;
-
+
i += 2;
nibble = hexval[(uint32_t)name[i]];
iface += (nibble << 4);
-
+
i += 2;
nibble = hexval[(uint32_t)name[i]];
iface += (nibble << 8);
-
+
i += 2;
nibble = hexval[(uint32_t)name[i]];
iface += (nibble << 12);
-
+
if (iface != 0)
{
qname = strdup(name);
if (qname == NULL) return NULL;
-
+
i = IPv6_REVERSE_LINK_LOCAL_SCOPE_ID_LOW;
qname[i] = '0';
qname[i + 2] = '0';
qname[i + 4] = '0';
qname[i + 6] = '0';
-
- if (outscope) *outscope = iface;
+
+ if (out_ifnum) *out_ifnum = iface;
}
}
+
return qname;
}
_mdns_make_query(const char* name, int class, int type, uint8_t *buf, uint32_t buflen)
{
uint32_t len = 0;
-
+
if (buf == NULL || buflen < (NS_HFIXEDSZ + NS_QFIXEDSZ)) return -1;
memset(buf, 0, NS_HFIXEDSZ);
HEADER *hp = (HEADER *)buf;
-
+
len += NS_HFIXEDSZ;
hp->id = arc4random();
hp->qr = 1;
hp->rd = 1;
hp->rcode = ns_r_noerror;
hp->qdcount = htons(1);
-
+
int n = _mdns_pack_domain_name(name, &buf[len], buflen - len);
if (n < 0) return -1;
-
+
len += n;
uint16_t word;
word = htons(type);
* initializes the context and starts a DNS-SD query.
*/
static DNSServiceErrorType
-_mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answer, uint32_t *anslen, const char* name, int class, int type, int kq)
+_mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answer, uint32_t *anslen, const char* name, int class, int type, const char *interface, int kq)
{
DNSServiceErrorType status;
-
+
int dns_flags = kDNSServiceFlagsShareConnection | kDNSServiceFlagsReturnIntermediates;
-
+
memset(ctx, 0, sizeof(mdns_query_context_t));
-
+
if (answer && anslen) {
// build a dummy DNS header to return to the caller
ctx->answer = answer;
ctx->anslen = _mdns_make_query(name, class, type, answer, ctx->ansmaxlen);
if (ctx->anslen <= 0) return -1;
}
-
+
ctx->type = type;
ctx->sd = _mdns_sdref;
ctx->kq = kq;
else if (type == ns_t_ptr && reply->h6) ctx->host = reply->h6;
else if (type != ns_t_srv && type != ns_t_cname) abort();
}
-
+
uint32_t iface = 0;
char *qname = _mdns_ipv6_extract_scope_id(name, &iface);
if (qname == NULL) qname = (char *)name;
+
+ if (interface != NULL)
+ {
+ /* get interface number from name */
+ int iface2 = if_nametoindex(interface);
+
+ /* balk if interface name lookup failed */
+ if (iface2 == 0) return -1;
+
+ /* balk if scope id is set AND interface is given AND they don't match */
+ if ((iface != 0) && (iface2 != 0) && (iface != iface2)) return -1;
+ if (iface2 != 0) iface = iface2;
+ }
+
if (_mdns_debug) printf(";; mdns query %s %d %d\n", qname, type, class);
status = DNSServiceQueryRecord(&ctx->sd, dns_flags, iface, qname, type, class, _mdns_query_callback, ctx);
- if (iface != 0) free(qname);
+ if (qname != name) free(qname);
return status;
}
{
int complete = _mdns_query_is_complete(ctx);
if (ctx == NULL) return complete;
-
+
if (ctx->sd != NULL) {
DNSServiceRefDeallocate(ctx->sd);
ctx->sd = NULL;
}
ctx->flags = 0;
ctx->kq = -1;
-
+
if (!complete) {
_mdns_hostent_clear(ctx->host);
ctx->anslen = -1;
context->flags = flags;
context->error = errorCode;
context->last_type = rrtype;
-
+
if (errorCode != kDNSServiceErr_NoError) {
if (_mdns_debug) printf(";; [%s %hu %hu]: error %d\n", fullname, rrtype, rrclass, errorCode);
goto wakeup_kevent;
}
- // embed the scope ID into link-local IPv6 addresses
+ // embed the scope ID into link-local IPv6 addresses
if (rrtype == ns_t_aaaa && rdlen == sizeof(struct in6_addr) &&
IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)rdata)) {
memcpy(&a6, rdata, rdlen);
a6.__u6_addr.__u6_addr16[1] = htons(ifIndex);
rdata = &a6;
- }
+ }
if (context->reply) {
char *name;
_mdns_hostent_append_alias(context->host, fullname);
if (reply->ttl == 0 || ttl < reply->ttl) reply->ttl = ttl;
-
+
switch (rrtype) {
- case ns_t_a:
+ case ns_t_a:
case ns_t_aaaa:
if (((rrtype == ns_t_a && context->host->host.h_addrtype == AF_INET) ||
(rrtype == ns_t_aaaa && context->host->host.h_addrtype == AF_INET6)) &&
uint16_t word;
uint32_t longword;
-
+
word = htons(rrtype);
memcpy(cp, &word, sizeof(word));
cp += sizeof(word);
longword = htonl(ttl);
memcpy(cp, &longword, sizeof(longword));
cp += sizeof(longword);
-
+
word = htons(rdlen);
memcpy(cp, &word, sizeof(word));
cp += sizeof(word);
}
int
-_mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply, uint32_t timeout_sec)
+_mdns_query_mDNSResponder(const char *name, int class, int type, const char *interface, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply, uint32_t timeout_sec)
{
DNSServiceErrorType err = 0;
int kq, n, wait = 1;
// log a warning for queries from the main thread
if (pthread_main_np()) asl_log(NULL, NULL, ASL_LEVEL_WARNING, "Warning: Libinfo call to mDNSResponder on main thread");
#endif // #if TARGET_OS_EMBEDDED
-
+
// Timeout Logic
// The kevent(2) API timeout parameter is used to enforce the total
// timeout of the DNS query. Each iteraion recalculates the relative
}
// issue (or reissue) the queries
- // unspecified type: do parallel A and AAAA
+ // unspecified type: do parallel A and AAAA
if (err == 0) {
err = _mdns_query_start(&ctx[n_ctx++], reply,
- answer, anslen,
- name, class,
- (type == 0) ? ns_t_a : type, kq);
+ answer, anslen,
+ name, class,
+ (type == 0) ? ns_t_a : type, interface, kq);
}
if (err == 0 && type == 0) {
err = _mdns_query_start(&ctx[n_ctx++], reply,
- answer, anslen,
- name, class, ns_t_aaaa, kq);
+ answer, anslen,
+ name, class, ns_t_aaaa, interface, kq);
}
if (err && _mdns_debug) printf(";; initialization error %d\n", err);
// try to reinitialize
// (re)register the fd with kqueue
int fd = DNSServiceRefSockFD(_mdns_sdref);
- EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
+ EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
n = kevent(kq, &ev, 1, NULL, 0, NULL);
pthread_mutex_unlock(&_mdns_mutex);
if (err != 0 || n != 0) break;
if (anslen) *anslen = ctx[0].anslen;
return res;
}
-
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
}
__private_extern__ si_item_t *
-search_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+search_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
{
int i, cat;
search_si_private_t *pp;
while (NULL != (src = search_get_module(pp, cat, &i)))
{
- item = si_host_byname(src, name, af, err);
+ item = si_host_byname(src, name, af, interface, err);
if (item != NULL)
{
si_cache_add_item(search_cat_cache(pp, cat), src, item);
}
__private_extern__ si_item_t *
-search_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
{
int i, cat;
search_si_private_t *pp;
while (NULL != (src = search_get_module(pp, cat, &i)))
{
- item = si_host_byaddr(src, addr, af, err);
+ item = si_host_byaddr(src, addr, af, interface, err);
if (item != NULL)
{
si_cache_add_item(search_cat_cache(pp, cat), src, item);
}
__private_extern__ si_list_t *
-search_srv_byname(si_mod_t *si, const char* qname, uint32_t *err)
+search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32_t *err)
{
int i, cat;
si_list_t *list = NULL;
if (src->sim_srv_byname != NULL)
{
- list = src->sim_srv_byname(src, qname, err);
+ list = src->sim_srv_byname(src, qname, interface, err);
if (list != NULL) return list;
}
}
}
__private_extern__ si_list_t *
-search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err)
+search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err)
{
int i, cat;
search_si_private_t *pp;
if (src->sim_addrinfo != NULL)
{
- list = src->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, err);
+ list = src->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, interface, err);
if (list != NULL) return list;
}
}
}
__private_extern__ si_item_t *
-search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
{
int i, cat;
search_si_private_t *pp;
while (NULL != (src = search_get_module(pp, cat, &i)))
{
- item = si_nameinfo(src, sa, flags, err);
+ item = si_nameinfo(src, sa, flags, interface, err);
if (item != NULL)
{
si_cache_add_item(search_cat_cache(pp, cat), src, item);
* we inet_ntop() and printf() and return the results.
*/
__private_extern__ si_item_t *
-si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
{
si_item_t *out = NULL;
const struct sockaddr *lookup_sa;
#if 0
if ((do_serv_lookup == 1) && (si->sim_nameinfo != NULL))
{
- return si->sim_nameinfo(si, lookup_sa, flags, err);
+ return si->sim_nameinfo(si, lookup_sa, flags, interface, err);
}
#endif
- si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, NULL);
+ si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, interface, NULL);
if (item != NULL)
{
struct hostent *h;
* Simple lookup via gethostbyname2(3) mechanism.
*/
static si_list_t *
-_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
si_item_t *h4_item = NULL, *h6_item = NULL;
struct hostent *h4 = NULL, *h6 = NULL;
{
if (family == AF_INET)
{
- h4_item = si_host_byaddr(si, nodeptr, AF_INET, NULL);
+ h4_item = si_host_byaddr(si, nodeptr, AF_INET, interface, NULL);
}
else if (family == AF_INET6)
{
- h6_item = si_host_byaddr(si, nodeptr, AF_INET6, NULL);
+ h6_item = si_host_byaddr(si, nodeptr, AF_INET6, interface, NULL);
}
}
else
{
if ((family == AF_INET) || (family == AF_UNSPEC))
{
- h4_item = si_host_byname(si, nodeptr, AF_INET, NULL);
+ h4_item = si_host_byname(si, nodeptr, AF_INET, interface, NULL);
}
-#if !TARGET_OS_EMBEDDED
+
if ((family == AF_INET6) || (family == AF_UNSPEC))
{
- h6_item = si_host_byname(si, nodeptr, AF_INET6, NULL);
+ h6_item = si_host_byname(si, nodeptr, AF_INET6, interface, NULL);
}
-#endif /* !TARGET_OS_EMBEDDED */
}
if (h4_item != NULL)
}
__private_extern__ si_list_t *
-si_srv_byname(si_mod_t *si, const char *qname, uint32_t *err)
+si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err)
{
if (si == NULL) return 0;
if (si->sim_srv_byname == NULL) return 0;
- return si->sim_srv_byname(si, qname, err);
+ return si->sim_srv_byname(si, qname, interface, err);
}
__private_extern__ int
}
static si_list_t *
-_gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
int i;
char *qname;
if (node == NULL || serv == NULL) return NULL;
asprintf(&qname, "%s.%s", serv, node);
- list = si_srv_byname(si, qname, err);
+ list = si_srv_byname(si, qname, interface, err);
free(qname);
/* Iterate the SRV records starting at lowest priority and attempt to
/* So that _gai_simple expects an integer service. */
flags |= AI_NUMERICSERV;
- result = _gai_simple(si, srv->target, &srv->port, family, socktype, proto, flags, err);
+ result = _gai_simple(si, srv->target, &srv->port, family, socktype, proto, flags, interface, err);
if (result)
{
break;
}
__private_extern__ si_list_t *
-si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
int numerichost, numericserv = 0;
const void *nodeptr = NULL, *servptr = NULL;
switch (family)
{
case AF_UNSPEC:
-#if TARGET_OS_EMBEDDED
- family = AF_INET;
-#endif
case AF_INET:
case AF_INET6:
break;
if ((flags & AI_SRV) != 0)
{
/* AI_SRV SPI */
- return _gai_srv(si, node, serv, family, socktype, proto, flags, err);
+ return _gai_srv(si, node, serv, family, socktype, proto, flags, interface, err);
}
else
{
else if ((si->sim_wants_addrinfo != NULL) && si->sim_wants_addrinfo(si))
{
/* or let the current module handle the host lookups intelligently */
- return si->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, err);
+ return si->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
}
/* fall back to a default path */
- return _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, err);
+ return _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
}
static struct addrinfo *
}
__private_extern__ si_item_t *
-si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, uint32_t *err)
+si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
{
int i, status, want, if4, if6;
struct ifaddrs *ifa, *ifap;
/* fetch IPv6 data if required */
if ((want == WANT_A6_ONLY) || (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) || (want == WANT_A6_PLUS_MAPPED_A4))
{
- item6 = si_host_byname(si, name, AF_INET6, (uint32_t *)err);
+ item6 = si_host_byname(si, name, AF_INET6, interface, (uint32_t *)err);
}
/* fetch IPv4 data if required */
if ((want == WANT_A4_ONLY) || (want == WANT_A6_PLUS_MAPPED_A4) || ((want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) && (item6 == NULL)))
{
- item4 = si_host_byname(si, name, AF_INET, (uint32_t *)err);
+ item4 = si_host_byname(si, name, AF_INET, interface, (uint32_t *)err);
}
if (want == WANT_A4_ONLY)
uint32_t call;
char *str1;
char *str2;
+ char *str3;
uint32_t num1;
uint32_t num2;
uint32_t num3;
}
__private_extern__ si_item_t *
-si_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
{
if (si == NULL) return NULL;
if (si->sim_host_byname == NULL) return NULL;
- return si->sim_host_byname(si, name, af, err);
+ return si->sim_host_byname(si, name, af, interface, err);
}
__private_extern__ si_item_t *
-si_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
{
if (si == NULL) return NULL;
if (si->sim_host_byaddr == NULL) return NULL;
- return si->sim_host_byaddr(si, addr, af, err);
+ return si->sim_host_byaddr(si, addr, af, interface, err);
}
__private_extern__ si_list_t *
}
__private_extern__ si_item_t *
-si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err)
+si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err)
{
if (si == NULL) return NULL;
case SI_CALL_GROUP_BYGID: return si_group_bygid(si, (gid_t)num1);
case SI_CALL_GROUPLIST: return si_grouplist(si, str1);
case SI_CALL_ALIAS_BYNAME: return si_alias_byname(si, str1);
- case SI_CALL_HOST_BYNAME: return si_host_byname(si, str1, num1, err);
- case SI_CALL_HOST_BYADDR: return si_host_byaddr(si, (void *)str1, num1, err);
+ case SI_CALL_HOST_BYNAME: return si_host_byname(si, str1, num1, str3, err);
+ case SI_CALL_HOST_BYADDR: return si_host_byaddr(si, (void *)str1, num1, str3, err);
case SI_CALL_NETWORK_BYNAME: return si_network_byname(si, str1);
case SI_CALL_NETWORK_BYADDR: return si_network_byaddr(si, num1);
case SI_CALL_SERVICE_BYNAME: return si_service_byname(si, str1, str2);
case SI_CALL_RPC_BYNUMBER: return si_rpc_bynumber(si, num1);
case SI_CALL_FS_BYSPEC: return si_fs_byspec(si, str1);
case SI_CALL_FS_BYFILE: return si_fs_byfile(si, str1);
- case SI_CALL_NAMEINFO: return si_nameinfo(si, (const struct sockaddr *)str1, num1, err);
- case SI_CALL_IPNODE_BYNAME: return si_ipnode_byname(si, (const char *)str1, num1, num2, err);
+ case SI_CALL_NAMEINFO: return si_nameinfo(si, (const struct sockaddr *)str1, num1, str3, err);
+ case SI_CALL_IPNODE_BYNAME: return si_ipnode_byname(si, (const char *)str1, num1, num2, str3, err);
case SI_CALL_MAC_BYNAME: return si_mac_byname(si, (const char *)str1);
case SI_CALL_MAC_BYMAC: return si_mac_bymac(si, (const char *)str1);
case SI_CALL_DNS_SEARCH:
{
if (si->sim_item_call == NULL) return NULL;
- return si->sim_item_call(si, call, str1, str2, num1, num2, err);
+ return si->sim_item_call(si, call, str1, str2, str3, num1, num2, err);
}
default: return NULL;
}
__private_extern__ si_list_t *
-si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
+si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
{
if (si == NULL) return NULL;
case SI_CALL_RPC_ALL: return si_rpc_all(si);
case SI_CALL_FS_ALL: return si_fs_all(si);
case SI_CALL_MAC_ALL: return si_mac_all(si);
- case SI_CALL_ADDRINFO: return si_addrinfo(si, str1, str2, num1, num2, num3, num4, err);
+ case SI_CALL_ADDRINFO: return si_addrinfo(si, str1, str2, num1, num2, num3, num4, str3, err);
default: return NULL;
}
}
static si_async_workunit_t *
-si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
+si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
{
si_async_workunit_t *r;
kern_return_t status;
mach_port_t reply, send;
mach_msg_type_name_t type;
- char *s1, *s2;
+ char *s1, *s2, *s3;
s1 = NULL;
s2 = NULL;
+ s3 = NULL;
if (si_call_str1_is_buffer(call))
{
}
}
+ if (str3 != NULL)
+ {
+ s3 = strdup(str3);
+ if (s3 == NULL)
+ {
+ if (s1 != NULL) free(s1);
+ if (s2 != NULL) free(s2);
+ return NULL;
+ }
+ }
+
r = (si_async_workunit_t *)calloc(1, sizeof(si_async_workunit_t));
if (r == NULL)
{
if (s1 != NULL) free(s1);
if (s2 != NULL) free(s2);
+ if (s3 != NULL) free(s3);
return NULL;
}
if (reply != MACH_PORT_NULL) mach_port_mod_refs(mach_task_self(), reply, MACH_PORT_RIGHT_RECEIVE, -1);
if (s1 != NULL) free(s1);
if (s2 != NULL) free(s2);
+ if (s3 != NULL) free(s3);
free(r);
return NULL;
}
r->call = call;
r->str1 = s1;
r->str2 = s2;
+ r->str3 = s3;
r->num1 = num1;
r->num2 = num2;
r->num3 = num3;
if (r->str1 != NULL) free(r->str1);
if (r->str2 != NULL) free(r->str2);
+ if (r->str3 != NULL) free(r->str3);
free(r);
}
if (x == NULL) pthread_exit(NULL);
r = (si_async_workunit_t *)x;
- if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->num1, r->num2, r->num3, r->num4, &(r->err));
- else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->num1, r->num2, &(r->err));
+ if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, r->num3, r->num4, &(r->err));
+ else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, &(r->err));
memset(&msg, 0, sizeof(mach_msg_empty_send_t));
}
mach_port_t
-si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
+si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
{
si_async_workunit_t *req;
pthread_attr_t attr;
/* if module does async on it's own, hand off the call */
if (si->sim_async_call != NULL)
{
- return si->sim_async_call(si, call, str1, str2, num1, num2, num3, num4, callback, context);
+ return si->sim_async_call(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
}
- req = si_async_workunit_create(si, call, str1, str2, num1, num2, num3, num4, callback, context);
+ req = si_async_workunit_create(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
if (req == NULL) return MACH_PORT_NULL;
/* start a new thread to do the work */
struct sockaddr *dns_server;
} si_dnspacket_t;
-typedef struct si_srv_s {
+typedef struct si_srv_s
+{
uint16_t priority;
uint16_t weight;
uint16_t port;
si_item_t *(*sim_alias_byname)(struct si_mod_s *si, const char *name);
si_list_t *(*sim_alias_all)(struct si_mod_s *si);
- si_item_t *(*sim_host_byname)(struct si_mod_s *si, const char *name, int af, uint32_t *err);
- si_item_t *(*sim_host_byaddr)(struct si_mod_s *si, const void *addr, int af, uint32_t *err);
+ si_item_t *(*sim_host_byname)(struct si_mod_s *si, const char *name, int af, const char *interface, uint32_t *err);
+ si_item_t *(*sim_host_byaddr)(struct si_mod_s *si, const void *addr, int af, const char *interface, uint32_t *err);
si_list_t *(*sim_host_all)(struct si_mod_s *si);
si_item_t *(*sim_network_byname)(struct si_mod_s *si, const char *name);
si_item_t *(*sim_mac_bymac)(struct si_mod_s *si, const char *mac);
si_list_t *(*sim_mac_all)(struct si_mod_s *si);
- si_list_t *(*sim_addrinfo)(struct si_mod_s *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err);
+ si_list_t *(*sim_addrinfo)(struct si_mod_s *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
int (*sim_wants_addrinfo)(struct si_mod_s *si);
- si_item_t *(*sim_nameinfo)(struct si_mod_s *si, const struct sockaddr *sa, int flags, uint32_t *err);
+ si_item_t *(*sim_nameinfo)(struct si_mod_s *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
- si_list_t *(*sim_srv_byname)(struct si_mod_s *si, const char *qname, uint32_t *err);
+ si_list_t *(*sim_srv_byname)(struct si_mod_s *si, const char *qname, const char *interface, uint32_t *err);
- si_item_t *(*sim_item_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err);
- si_list_t *(*sim_list_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
+ si_item_t *(*sim_item_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
+ si_list_t *(*sim_list_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
- mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
+ mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
void (*sim_async_cancel)(mach_port_t p);
void (*sim_async_handle_reply)(mach_msg_header_t *msg);
} si_mod_t;
__private_extern__ si_item_t *si_alias_byname(struct si_mod_s *si, const char *name);
__private_extern__ si_list_t *si_alias_all(struct si_mod_s *si);
-__private_extern__ si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err);
-__private_extern__ si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err);
+__private_extern__ si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err);
+__private_extern__ si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err);
__private_extern__ si_list_t *si_host_all(si_mod_t *si);
__private_extern__ si_item_t *si_mac_byname(struct si_mod_s *si, const char *name);
__private_extern__ si_list_t *si_fs_all(si_mod_t *si);
__private_extern__ int si_wants_addrinfo(si_mod_t *s);
-__private_extern__ si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err);
+__private_extern__ si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
-__private_extern__ si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err);
-__private_extern__ si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, uint32_t *err);
+__private_extern__ si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
+__private_extern__ si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err);
-__private_extern__ si_list_t *si_srv_byname(si_mod_t *si, const char *qname, uint32_t *err);
+__private_extern__ si_list_t *si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err);
-__private_extern__ si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err);
-__private_extern__ si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
+__private_extern__ si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
+__private_extern__ si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
-extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
+extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
extern void si_async_cancel(mach_port_t p);
extern void si_async_handle_reply(mach_msg_header_t *msg);