static kern_return_t register_bootstrap_service(void) { kern_return_t kr; mach_port_t service_send_port, service_rcv_port; // Let us attempt to check in.... This routine will look up the service // by name and attempt to return receive rights to the service port. kr = bootstrap_check_in(bootstrap_port, (char *)SERVICE_NAME, &service_rcv_port); if (kr == KERN_SUCCESS) server_priv_port = bootstrap_port; else if (kr == BOOTSTRAP_UNKNOWN_SERVICE) { // The service does not exist, so let us create it.... kr = bootstrap_create_server(bootstrap_port, SERVICE_CMD, getuid(), // server uid FALSE, // not on-demand &server_priv_port); if (kr != KERN_SUCCESS) return kr; // We can now use server_priv_port to declare services associated // with this server by calling bootstrap_create_service() and passing // server_priv_port as the bootstrap port. // Create a service called SERVICE_NAME, and return send rights to // that port in service_send_port. kr = bootstrap_create_service(server_priv_port, (char *)SERVICE_NAME, &service_send_port); if (kr != KERN_SUCCESS) { mach_port_deallocate(mach_task_self(), server_priv_port); return kr; } // Check in and get receive rights to the service port of the service. kr = bootstrap_check_in(server_priv_port, (char *)SERVICE_NAME, &service_rcv_port); if (kr != KERN_SUCCESS) { mach_port_deallocate(mach_task_self(), server_priv_port); mach_port_deallocate(mach_task_self(), service_send_port); return kr; } } // We are not a Mach port server, so we do not need this port. However, // we still will have a service with the Bootstrap Server, and so we // will be relaunched if we exit. mach_port_destroy(mach_task_self(), service_rcv_port); return kr; }
static mach_port_t checkin_or_register(char *bname) { kern_return_t kr; mach_port_t mp; /* If we're started by launchd or the old mach_init */ kr = bootstrap_check_in(bootstrap_port, bname, &mp); if (kr == KERN_SUCCESS) return mp; /* We probably were not started by launchd or the old mach_init */ kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); if (kr != KERN_SUCCESS) { fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND); if (kr != KERN_SUCCESS) { fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } kr = bootstrap_register(bootstrap_port, bname, mp); if (kr != KERN_SUCCESS) { fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } return mp; }
int main(int argc, char **argv) { kern_return_t kr; mach_port_t service_port = MACH_PORT_NULL; openlog("eapolcfg_auth", LOG_CONS | LOG_PID, LOG_DAEMON); if (geteuid() != 0) { syslog(LOG_ERR, "not running as root - exiting"); exit(EX_CONFIG); } kr = bootstrap_check_in(bootstrap_port, EAPOLCFG_AUTH_SERVER, &service_port); if (kr != BOOTSTRAP_SUCCESS) { syslog(LOG_ERR, "bootstrap_check_in() failed: %s", bootstrap_strerror(kr)); exit(EX_UNAVAILABLE); } start_service(service_port); while (1) { SInt32 rlStatus; rlStatus = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 15.0, TRUE); if (rlStatus == kCFRunLoopRunTimedOut) { if (S_handled_request == FALSE) { /* we didn't handle a request in the last time interval */ break; } S_handled_request = FALSE; } } exit(EX_OK); return (0); }
static mach_port_t register_service(const char *service_name) { mach_port_t port = MACH_PORT_NULL; kern_return_t kr; if (KERN_SUCCESS == (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port))) { if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND))) helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); else return port; } if (KERN_SUCCESS != (kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port))) { helplog(ASL_LEVEL_ERR, "mach_port_allocate: %s", mach_error_string(kr)); goto error; } if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND))) { helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %s", mach_error_string(kr)); goto error; } // XXX bootstrap_register does not modify its second argument, but the prototype does not include const. if (KERN_SUCCESS != (kr = bootstrap_register(bootstrap_port, (char *)service_name, port))) { helplog(ASL_LEVEL_ERR, "bootstrap_register failed: %s", mach_error_string(kr)); goto error; } return port; error: if (MACH_PORT_NULL != port) mach_port_deallocate(mach_task_self(), port); return MACH_PORT_NULL; }
Boolean SetupMIGServer() { Boolean result = true; kern_return_t kern_result = KERN_SUCCESS; CFMachPortRef upsdMachPort = NULL; // must release mach_port_t ups_port = MACH_PORT_NULL; /*if (IOUPSMIGServerIsRunning(&bootstrap_port, NULL)) { result = false; goto finish; }*/ kern_result = task_get_bootstrap_port(mach_task_self(), &bootstrap_port); if (kern_result != KERN_SUCCESS) { result = false; goto finish; } gMainRunLoop = CFRunLoopGetCurrent(); if (!gMainRunLoop) { result = false; goto finish; } kern_result = bootstrap_check_in( bootstrap_port, kIOUPSPlugInServerName, &ups_port); if (BOOTSTRAP_SUCCESS != kern_result) { syslog(LOG_ERR, "ioupsd: bootstrap_check_in \"%s\" error = %d\n", kIOUPSPlugInServerName, kern_result); } else { upsdMachPort = CFMachPortCreateWithPort(kCFAllocatorDefault, ups_port, upsd_mach_port_callback, NULL, NULL); gClientRequestRunLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, upsdMachPort, 0); if (!gClientRequestRunLoopSource) { result = false; goto finish; } CFRunLoopAddSource(gMainRunLoop, gClientRequestRunLoopSource, kCFRunLoopDefaultMode); } finish: if (gClientRequestRunLoopSource) CFRelease(gClientRequestRunLoopSource); if (upsdMachPort) CFRelease(upsdMachPort); return result; }
void* AppleCMIODPSampleNewPlugIn(CFAllocatorRef allocator, CFUUIDRef requestedTypeUUID) { if (not CFEqual(requestedTypeUUID, kCMIOHardwarePlugInTypeID)) return 0; try { // Before going any further, make sure the SampleAssistant process is registerred with Mach's bootstrap service. Normally, this would be done by having an appropriately // configured plist in /Library/LaunchDaemons, but if that is done then the process will be owned by root, thus complicating the debugging process. Therefore, in the event that the // plist is missing (as would be the case for most debugging efforts) attempt to register the SampleAssistant now. It will fail gracefully if allready registered. mach_port_t assistantServicePort; name_t assistantServiceName = "com.apple.cmio.DPA.Sample"; kern_return_t err = bootstrap_look_up(bootstrap_port, assistantServiceName, &assistantServicePort); if (BOOTSTRAP_SUCCESS != err) { // Create an URL to SampleAssistant that resides at "/Library/CoreMediaIO/Plug-Ins/DAL/Sample.plugin/Contents/Resources/SampleAssistant" CACFURL assistantURL(CFURLCreateWithFileSystemPath(NULL, CFSTR("/Library/CoreMediaIO/Plug-Ins/DAL/Sample.plugin/Contents/Resources/SampleAssistant"), kCFURLPOSIXPathStyle, false)); ThrowIf(not assistantURL.IsValid(), CAException(-1), "AppleCMIODPSampleNewPlugIn: unable to create URL for the SampleAssistant"); // Get the maximum size of the of the file system representation of the SampleAssistant's absolute path CFIndex length = CFStringGetMaximumSizeOfFileSystemRepresentation(CACFString(CFURLCopyFileSystemPath(CACFURL(CFURLCopyAbsoluteURL(assistantURL.GetCFObject())).GetCFObject(), kCFURLPOSIXPathStyle)).GetCFString()); // Get the file system representation CAAutoFree<char> path(length); (void) CFURLGetFileSystemRepresentation(assistantURL.GetCFObject(), true, reinterpret_cast<UInt8*>(path.get()), length); mach_port_t assistantServerPort; err = bootstrap_create_server(bootstrap_port, path, getuid(), true, &assistantServerPort); ThrowIf(BOOTSTRAP_SUCCESS != err, CAException(err), "AppleCMIODPSampleNewPlugIn: couldn't create server"); err = bootstrap_check_in(assistantServerPort, assistantServiceName, &assistantServicePort); // The server port is no longer needed so get rid of it (void) mach_port_deallocate(mach_task_self(), assistantServerPort); // Make sure the call to bootstrap_create_service() succeeded ThrowIf(BOOTSTRAP_SUCCESS != err, CAException(err), "AppleCMIODPSampleNewPlugIn: couldn't create SampleAssistant service port"); } // The service port is not longer needed so get rid of it (void) mach_port_deallocate(mach_task_self(), assistantServicePort); CMIO::DP::Sample::PlugIn* plugIn = new CMIO::DP::Sample::PlugIn(requestedTypeUUID); plugIn->Retain(); return plugIn->GetInterface(); } catch (...) { return NULL; } }
__private_extern__ void server_init() { serverSessionRef mySession; CFRunLoopSourceRef rls; char *service_name; mach_port_t service_port = MACH_PORT_NULL; kern_return_t status; service_name = getenv("SCD_SERVER"); if (!service_name) { service_name = SCD_SERVER; } /* Check "configd" server status */ status = bootstrap_check_in(bootstrap_port, service_name, &service_port); switch (status) { case BOOTSTRAP_SUCCESS : /* if we are being [re-]started by launchd */ break; case BOOTSTRAP_NOT_PRIVILEGED : /* if another instance of the server is starting */ SCLog(TRUE, LOG_ERR, CFSTR("'%s' server already starting"), service_name); exit (EX_UNAVAILABLE); case BOOTSTRAP_SERVICE_ACTIVE : /* if another instance of the server is active */ SCLog(TRUE, LOG_ERR, CFSTR("'%s' server already active"), service_name); exit (EX_UNAVAILABLE); default : SCLog(TRUE, LOG_ERR, CFSTR("server_init bootstrap_check_in(..., '%s', ...) failed: %s"), service_name, bootstrap_strerror(status)); exit (EX_UNAVAILABLE); } /* Create the primary / new connection port and backing session */ mySession = addSession(service_port, serverMPCopyDescription); configd_port = mySession->serverPort; /* * Create and add a run loop source for the port and add this source * to the default run loop mode. */ rls = CFMachPortCreateRunLoopSource(NULL, configd_port, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); return; }
static int mach_listen(const char *name, xpc_port_t *port) { mach_port_t mp; kern_return_t kr; kr = bootstrap_check_in(bootstrap_port, name, &mp); if (kr != KERN_SUCCESS) { debugf("bootstrap_check_in failed kr=%d", kr); errno = EBUSY; return (-1); } *port = mp; return (0); }
kern_return_t bootstrap_status(mach_port_t bp, name_t service_name, bootstrap_status_t *service_active) { mach_port_t p; if (bootstrap_check_in(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { mach_port_mod_refs(mach_task_self(), p, MACH_PORT_RIGHT_RECEIVE, -1); *service_active = BOOTSTRAP_STATUS_ON_DEMAND; return BOOTSTRAP_SUCCESS; } else if (bootstrap_look_up(bp, service_name, &p) == BOOTSTRAP_SUCCESS) { mach_port_deallocate(mach_task_self(), p); *service_active = BOOTSTRAP_STATUS_ACTIVE; return BOOTSTRAP_SUCCESS; } return BOOTSTRAP_UNKNOWN_SERVICE; }
static mach_port_t register_service(const char *service_name) { mach_port_t port = MACH_PORT_NULL; kern_return_t kr; if (KERN_SUCCESS != (kr = bootstrap_check_in(bootstrap_port, (char *)service_name, &port))) { helplog(ASL_LEVEL_ERR, "bootstrap_check_in: %d %X %s", kr, kr, mach_error_string(kr)); return MACH_PORT_NULL; } if (KERN_SUCCESS != (kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND))) { helplog(ASL_LEVEL_ERR, "mach_port_insert_right: %d %X %s", kr, kr, mach_error_string(kr)); mach_port_deallocate(mach_task_self(), port); return MACH_PORT_NULL; } return port; }
int ppp_mach_start_server() { kern_return_t status; CFRunLoopSourceRef rls; mach_port_t our_port = MACH_PORT_NULL; CFMachPortContext context = { 0, (void *)1, NULL, NULL, serverMPCopyDescription }; status = bootstrap_check_in(bootstrap_port, PPPCONTROLLER_SERVER, &our_port); if (status != BOOTSTRAP_SUCCESS) { SCLog(TRUE, LOG_ERR, CFSTR("PPPController: bootstrap_check_in \"%s\" error = %s"), PPPCONTROLLER_SERVER, bootstrap_strerror(status)); return -1; } gServer_cfport = _SC_CFMachPortCreateWithPort("PPPController", our_port, server_handle_request, &context); if (!gServer_cfport) { SCLog(TRUE, LOG_ERR, CFSTR("PPPController: cannot create mach port")); return -1; } rls = CFMachPortCreateRunLoopSource(0, gServer_cfport, 0); if (!rls) { SCLog(TRUE, LOG_ERR, CFSTR("PPPController: cannot create rls")); CFRelease(gServer_cfport); gServer_cfport = NULL; return -1; } gControllerRunloop = CFRunLoopGetCurrent(); CFRunLoopAddSource(gControllerRunloop, rls, kCFRunLoopDefaultMode); CFRunLoopAddSource(gControllerRunloop, gTerminalrls, kCFRunLoopDefaultMode); CFRelease(rls); return 0; }
static mach_port_t server_port(void *info) { if (!_server_port) { kern_return_t ret; ret = bootstrap_check_in(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, &_server_port); if (ret == KERN_SUCCESS) { secdebug("server", "bootstrap_check_in() succeeded, return checked in port: 0x%x\n", _server_port); return _server_port; } #if 0 ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &_server_port); if (ret != KERN_SUCCESS) { secdebug("server", "mach_port_allocate(): 0x%x: %s\n", ret, mach_error_string(ret)); exit(2); } ret = mach_port_insert_right(mach_task_self(), _server_port, _server_port, MACH_MSG_TYPE_MAKE_SEND); if (ret != KERN_SUCCESS) { secdebug("server", "mach_port_insert_right(): 0x%x: %s\n", ret, mach_error_string(ret)); exit(3); } ret = bootstrap_register(bootstrap_port, SECURITYSERVER_BOOTSTRAP_NAME, _server_port); if (ret != BOOTSTRAP_SUCCESS) { secdebug("server", "bootstrap_register(): 0x%x: %s\n", ret, mach_error_string(ret)); exit(4); } #else exit(1); #endif } return _server_port; }
int main() { kern_return_t kr; mach_port_t bport, port, pset; struct msg_recv message; struct msg_send reply; struct kevent64_s kev; int kq, r; task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, &bport); syslog(LOG_ERR, "bootstrap port: %d", bport); kr = bootstrap_check_in(bootstrap_port, "mach.service-test", &port); if (kr != KERN_SUCCESS) { syslog(LOG_ERR, "bootstrap_check_in: kr=%d", kr); exit(1); } syslog(LOG_ERR, "service port: %d", port); kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &pset); if (kr != KERN_SUCCESS) { syslog(LOG_ERR, "mach_port_allocate: kr=%d", kr); exit(1); } kr = mach_port_move_member(mach_task_self(), port, pset); if (kr != KERN_SUCCESS) { syslog(LOG_ERR, "mach_port_move_member: kr=%d", kr); exit(1); } kq = kqueue(); syslog(LOG_ERR, "kqueue fd: %d", kq); memset(&kev, 0, sizeof(struct kevent64_s)); EV_SET64(&kev, pset, EVFILT_MACHPORT, EV_ADD | EV_ENABLE, 0, 0, 0, 0, 0); if (kevent64(kq, &kev, 1, NULL, 0, 0, NULL) < 0) { syslog(LOG_ERR, "kevent64: %s (%d)", strerror(errno), errno); return 0; } for (;;) { message.hdr.msgh_local_port = port; message.hdr.msgh_size = sizeof(struct msg_recv); r = kevent64(kq, NULL, 0, &kev, 1, 0, NULL); if (r < 0) { syslog(LOG_ERR, "kevent64 failed: %s (%d)", strerror(errno), errno); continue; } syslog(LOG_ERR, "kevent64: events=%d", r); kr = mach_msg_receive((mach_msg_header_t *)&message); if (kr != KERN_SUCCESS) syslog(LOG_ERR, "mach_msg_receive failure: kr=%d", kr); else syslog(LOG_ERR, "received message on port %d: body=%s", message.hdr.msgh_remote_port, message.body); memset(&reply, 0, sizeof(struct msg_send)); sprintf(&reply.body[0], "hello buddy"); reply.hdr.msgh_local_port = MACH_PORT_NULL; reply.hdr.msgh_remote_port = message.hdr.msgh_remote_port; reply.hdr.msgh_size = sizeof(struct msg_send); reply.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); kr = mach_msg_send((mach_msg_header_t *)&reply); if (kr != KERN_SUCCESS) syslog(LOG_ERR, "mach_msg_send failure: kr=%d", kr); } }
int32_t k5_ipc_server_listen_loop (void) { /* Run the Mach IPC listen loop. * This will call k5_ipc_server_create_client_connection for new clients * and k5_ipc_server_request for existing clients */ kern_return_t err = KERN_SUCCESS; char *service = NULL; char *lookup = NULL; mach_port_t lookup_port = MACH_PORT_NULL; mach_port_t boot_port = MACH_PORT_NULL; mach_port_t previous_notify_port = MACH_PORT_NULL; if (!err) { err = k5_ipc_server_get_lookup_and_service_names (&lookup, &service); } if (!err) { /* Get the bootstrap port */ err = task_get_bootstrap_port (mach_task_self (), &boot_port); } if (!err) { /* We are an on-demand server so our lookup port already exists. */ err = bootstrap_check_in (boot_port, lookup, &lookup_port); } if (!err) { /* We are an on-demand server so our service port already exists. */ err = bootstrap_check_in (boot_port, service, &g_service_port); } if (!err) { /* Create the port set that the server will listen on */ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &g_notify_port); } if (!err) { /* Ask for notification when the server port has no more senders * A send-once right != a send right so our send-once right will * not interfere with the notification */ err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS, true, g_notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous_notify_port); } if (!err) { /* Create the port set that the server will listen on */ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, &g_listen_port_set); } if (!err) { /* Add the lookup port to the port set */ err = mach_port_move_member (mach_task_self (), lookup_port, g_listen_port_set); } if (!err) { /* Add the service port to the port set */ err = mach_port_move_member (mach_task_self (), g_service_port, g_listen_port_set); } if (!err) { /* Add the notify port to the port set */ err = mach_port_move_member (mach_task_self (), g_notify_port, g_listen_port_set); } while (!err && !g_ready_to_quit) { /* Handle one message at a time so we can check to see if * the server wants to quit */ err = mach_msg_server_once (k5_ipc_request_demux, K5_IPC_MAX_MSG_SIZE, g_listen_port_set, MACH_MSG_OPTION_NONE); } /* Clean up the ports and strings */ if (MACH_PORT_VALID (g_notify_port)) { mach_port_destroy (mach_task_self (), g_notify_port); g_notify_port = MACH_PORT_NULL; } if (MACH_PORT_VALID (g_listen_port_set)) { mach_port_destroy (mach_task_self (), g_listen_port_set); g_listen_port_set = MACH_PORT_NULL; } if (MACH_PORT_VALID (boot_port)) { mach_port_deallocate (mach_task_self (), boot_port); } free (service); free (lookup); return err; }
/* * Called once before fuzzing starts. Prepare mach ports for attaching crash reporter. */ bool arch_archInit(honggfuzz_t * hfuzz) { char plist[PATH_MAX]; snprintf(plist, sizeof(plist), "/Users/%s/Library/Preferences/com.apple.DebugSymbols.plist", getlogin()); if (files_exists(plist)) { LOG_W ("honggfuzz won't work if DBGShellCommands are set in ~/Library/Preferences/com.apple.DebugSymbols.plist"); } /* * Allocate exception port. */ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &g_exception_port) != KERN_SUCCESS) { return false; } /* * Insert exception receive port. */ if (mach_port_insert_right (mach_task_self(), g_exception_port, g_exception_port, MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS) { return false; } /* * Get bootstrap port. */ mach_port_t bootstrap = MACH_PORT_NULL; if (task_get_bootstrap_port(mach_task_self(), &bootstrap) != KERN_SUCCESS) { return false; } /* * Generate and register exception port service. */ snprintf(g_service_name, sizeof(g_service_name), "com.google.code.honggfuzz.%d", (int)util_rndGet(0, 999999)); if (bootstrap_check_in(bootstrap, g_service_name, &g_exception_port) != KERN_SUCCESS) { return false; } /* * Create a collection thread to catch the exceptions from the * children */ pthread_t exception_thread; if (pthread_create(&exception_thread, NULL, wait_for_exception, 0)) { LOG_F("Parent: could not create thread to wait for child's exception"); return false; } if (pthread_detach(exception_thread)) { LOG_F("Parent: could not detach thread to wait for child's exception"); return false; } return true; }
/*ARGSUSED*/ int benchmark_initbatch(void *tsd) { /* * initialize your state variables here second */ long pid; tsd_t *ts = (tsd_t *)tsd; ts->server_mode = -1; ts->verbose = opt_verbose; ts->oneway = opt_oneway; ts->overwrite = 0; ts->msg_type = opt_msg_type; ts->num_ints = opt_num_ints; ts->num_msgs = opt_num_msgs; ts->server_port_name = opt_server_port_name; ts->server_port = MACH_PORT_NULL; ts->reply_port = MACH_PORT_NULL; ts->request_msg = NULL; ts->request_msg_size = 0; ts->reply_msg = NULL; ts->reply_msg_size = 0; switch (ts->msg_type) { case msg_type_trivial: ts->request_msg_size = sizeof(ipc_trivial_message); break; case msg_type_inline: ts->request_msg_size = sizeof(ipc_inline_message) + sizeof(u_int32_t) * ts->num_ints; break; case msg_type_complex: ts->request_msg_size = sizeof(ipc_complex_message); ts->ints = malloc(sizeof(u_int32_t) * ts->num_ints); break; } ts->request_msg = malloc(ts->request_msg_size); ts->reply_msg = malloc(ts->reply_msg_size); if (ts->server_mode) { kern_return_t ret = 0; mach_port_t bsport; ts->reply_msg_size -= sizeof(mach_msg_trailer_t); ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(ts->server_port)); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(): ", ret); exit(1); } ret = mach_port_insert_right(mach_task_self(), ts->server_port, ts->server_port, MACH_MSG_TYPE_MAKE_SEND); if (KERN_SUCCESS != ret) { mach_error("mach_port_insert_right(): ", ret); exit(1); } ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } ret = bootstrap_check_in(bsport, (char *)ts->server_port_name, &ts->server_port); if (KERN_SUCCESS != ret) { mach_error("bootstrap_register(): ", ret); exit(1); } } else { /* client mode */ kern_return_t ret = 0; mach_port_t bsport; ts->request_msg_size -= sizeof(mach_msg_trailer_t); ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(ts->reply_port)); if (KERN_SUCCESS != ret) { mach_error("mach_port_allocate(): ", ret); exit(1); } ret = task_get_bootstrap_port(mach_task_self(), &bsport); if (KERN_SUCCESS != ret) { mach_error("task_get_bootstrap_port(): ", ret); exit(1); } ret = bootstrap_look_up(bsport, (char *)ts->server_port_name, &(ts->server_port)); if (KERN_SUCCESS != ret) { mach_error("bootstrap_look_up(): ", ret); exit(1); } } if (ts->verbose) { if (ts->server_mode) { printf("Server waiting for IPC messages from client on port '%s'.\n", ts->server_port_name); } else { printf("Client sending %d %s IPC messages to port '%s' in %s mode.\n", ts->num_msgs, (ts->msg_type == msg_type_inline) ? "inline" : ((ts->msg_type == msg_type_complex) ? "complex" : "trivial"), ts->server_port_name, (ts->oneway ? "oneway" : "rpc")); } } pid = fork(); switch (pid) { case 0: server(tsd); exit(0); break; case -1: return (-1); default: ts->pid = pid; break; } return (0); }
/* * kern_return_t * bootstrap_check_in(mach_port_t bootstrap_port, * name_t service_name, * mach_port_t *service_portp) * * Returns receive rights to service_port of service named by service_name. * * Errors: Returns appropriate kernel errors on rpc failure. * Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist. * Returns BOOTSTRAP_SERVICE_NOT_DECLARED, if service not declared * in /etc/bootstrap.conf. * Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been * registered or checked-in. */ kern_return_t x_bootstrap_check_in( mach_port_t bootstrap_port, name_t service_name, mach_port_t *service_portp) { kern_return_t result; mach_port_t previous; service_t *servicep; server_t *serverp; bootstrap_info_t *bootstrap; serverp = lookup_server_by_port(bootstrap_port); bootstrap = lookup_bootstrap_by_port(bootstrap_port); debug("Service checkin attempt for service %s bootstrap %x", service_name, bootstrap_port); servicep = lookup_service_by_name(bootstrap, service_name); if (servicep == NULL || servicep->port == MACH_PORT_NULL) { debug("bootstrap_check_in service %s unknown%s", service_name, forward_ok ? " forwarding" : ""); return forward_ok ? bootstrap_check_in( inherited_bootstrap_port, service_name, service_portp) : BOOTSTRAP_UNKNOWN_SERVICE; } if (servicep->server != NULL && servicep->server != serverp) { debug("bootstrap_check_in service %s not privileged", service_name); return BOOTSTRAP_NOT_PRIVILEGED; } if (!canReceive(servicep->port)) { ASSERT(servicep->isActive); debug("bootstrap_check_in service %s already active", service_name); return BOOTSTRAP_SERVICE_ACTIVE; } debug("Checkin service %s for bootstrap %x", service_name, bootstrap->bootstrap_port); ASSERT(servicep->isActive == FALSE); servicep->isActive = TRUE; if (servicep->server != NULL_SERVER) { /* registered server - service needs backup */ serverp->activity++; serverp->active_services++; result = mach_port_request_notification( mach_task_self(), servicep->port, MACH_NOTIFY_PORT_DESTROYED, 0, backup_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); if (result != KERN_SUCCESS) kern_fatal(result, "mach_port_request_notification"); } else { /* one time use/created service */ servicep->servicetype = REGISTERED; result = mach_port_request_notification( mach_task_self(), servicep->port, MACH_NOTIFY_DEAD_NAME, 0, notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous); if (result != KERN_SUCCESS) kern_fatal(result, "mach_port_request_notification"); else if (previous != MACH_PORT_NULL) { debug("deallocating old notification port (%x) for checked in service %x", previous, servicep->port); result = mach_port_deallocate( mach_task_self(), previous); if (result != KERN_SUCCESS) kern_fatal(result, "mach_port_deallocate"); } } info("Check-in service %x in bootstrap %x: %s", servicep->port, servicep->bootstrap->bootstrap_port, servicep->name); *service_portp = servicep->port; return BOOTSTRAP_SUCCESS; }
int main(){ mach_port_t boot_port; mach_port_t server_port; mach_port_t task_self_port = task_self_trap(); kern_return_t result; receive_message_t received_msg; send_message_t sent_msg; mach_msg_header_t* mach_hdr; char print_buffer[1024]; str_mach_port_name(task_self_port, print_buffer, 1024); printf("Task self port: %s\n", print_buffer); /* Get the bootstrap port for the current login context. */ result = task_get_bootstrap_port(task_self_port, &boot_port); ERR_EXIT(result, "task_get_bootstrap_port failed."); str_mach_port_name(boot_port, print_buffer, 1024); printf("Bootstrap port: %s\n", print_buffer); /* check in our service directly. No need for resgister etc. */ result = bootstrap_check_in(boot_port, SERVER_NAME, &server_port); ERR_EXIT(result, "Bootstrap Checkin Failed.\n"); str_mach_port_name(server_port, print_buffer, 1024); printf("Server port: %s\n", print_buffer); /* prepare for doing the real work. */ do { mach_hdr = &(received_msg.msg_header); mach_hdr->msgh_id = MULTIPLEX_ID; mach_hdr->msgh_local_port = MACH_PORT_NULL; mach_hdr->msgh_remote_port = MACH_PORT_NULL; mach_hdr->msgh_size = sizeof(received_msg); mach_hdr->msgh_bits = 0; result = mach_msg(mach_hdr, MACH_RCV_MSG, 0, mach_hdr->msgh_size, server_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if(result != KERN_SUCCESS){ fprintf(stderr, "mach_msg(receive) failed. Error: %s\n", mach_error_string(result)); print_mach_msg_header(stderr, mach_hdr); continue; } fprintf(stdout, "**** Received message with header:\n"); print_mach_msg_header(stdout, mach_hdr); enumerate_ports_with_status(stdout); // Use LLDB to insert the above statement to find out // all the available ports in the process. reverse(received_msg.response, sent_msg.request); mach_hdr=&(sent_msg.msg_header); mach_hdr->msgh_id = MULTIPLEX_ID; mach_hdr->msgh_remote_port = received_msg.msg_header.msgh_remote_port; mach_hdr->msgh_local_port = MACH_PORT_NULL; mach_hdr->msgh_bits = received_msg.msg_header.msgh_bits; mach_hdr->msgh_size = sizeof(sent_msg); fprintf(stdout, "**** Sending response with header:\n"); print_mach_msg_header(stdout, mach_hdr); fprintf(stdout, "\n\nList of ports and their status:\n"); result = mach_msg(mach_hdr, MACH_SEND_MSG, mach_hdr->msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if(result != KERN_SUCCESS){ fprintf(stderr, "mach_msg(send) failed. Error: %s\n", mach_error_string(result)); continue; } fprintf(stdout, "Successfully sent the message.\n"); } while (1); return 0; }