/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 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 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 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * 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@ */ #import #import #import #import #import #import #import #import #import "dprintf.h" #import "threadcompat.h" #import "machcompat.h" #import "ipconfig.h" #import "ipconfigd.h" #import "ipconfig_ext.h" #import "globals.h" //static char request_buf[1024]; static char reply_buf[1024]; static uid_t S_uid = -1; static gid_t S_gid = -1; #ifdef MOSX static __inline__ void read_trailer(msg_header_t * request) { mach_msg_format_0_trailer_t *trailer; trailer = (mach_msg_security_trailer_t *)((vm_offset_t)request + round_msg(request->msgh_size)); if ((trailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0) && (trailer->msgh_trailer_size >= MACH_MSG_TRAILER_FORMAT_0_SIZE)) { S_uid = trailer->msgh_sender.val[0]; S_gid = trailer->msgh_sender.val[1]; } else { /* XXX * Change 0 to -1 in the following two lines when CF is fixed. */ S_uid = 0; S_gid = 0; } } #else MOSX static __inline__ void read_trailer(msg_header_t * request) { return; } #endif MOSX kern_return_t _ipconfig_config_if(port_t p, if_name_t name) { dprintf(("config called with %s\n", name)); return (KERN_SUCCESS); } kern_return_t _ipconfig_config_all(port_t p) { dprintf(("config all called\n")); return (KERN_SUCCESS); } kern_return_t _ipconfig_wait_if(port_t p, if_name_t name) { dprintf(("Waiting for %s to complete\n", name)); if (S_uid == 0 && wait_if(name) == TRUE) return (KERN_SUCCESS); return (KERN_FAILURE); } kern_return_t _ipconfig_wait_all(port_t p) { dprintf(("Waiting for all interfaces to complete\n")); if (S_uid == 0) { wait_all(); return (KERN_SUCCESS); } return (KERN_FAILURE); } kern_return_t _ipconfig_if_name(port_t p, int intface, if_name_t name) { dprintf(("Getting interface name\n")); if (get_if_name(intface, name) == TRUE) return (KERN_SUCCESS); return (KERN_FAILURE); } kern_return_t _ipconfig_if_addr(port_t p, if_name_t name, u_int32_t * addr) { dprintf(("Getting interface address\n")); if (get_if_addr(name, addr) == TRUE) return (KERN_SUCCESS); return (KERN_FAILURE); } kern_return_t _ipconfig_if_count(port_t p, int * count) { dprintf(("Getting interface count\n")); *count = get_if_count(); return (KERN_SUCCESS); } kern_return_t _ipconfig_get_option(port_t p, if_name_t name, int option_code, inline_data_t option_data, unsigned int * option_dataCnt) { if (get_if_option(name, option_code, option_data, option_dataCnt) == TRUE) { return (KERN_SUCCESS); } return (KERN_FAILURE); } kern_return_t _ipconfig_get_packet(port_t p, if_name_t name, inline_data_t packet_data, unsigned int * packet_dataCnt) { if (get_if_packet(name, packet_data, packet_dataCnt) == TRUE) { return (KERN_SUCCESS); } return (KERN_FAILURE); } kern_return_t _ipconfig_set(port_t p, if_name_t name, ipconfig_method_t method, inline_data_t method_data, unsigned int method_data_len, ipconfig_status_t * status) { if (S_uid != 0) { *status = ipconfig_status_permission_denied_e; } else { *status = set_if(name, method, method_data, method_data_len, NULL); } return (KERN_SUCCESS); } #if 0 void server_loop(void * arg) { msg_header_t * request = (msg_header_t *)request_buf; msg_header_t * reply = (msg_header_t *)reply_buf; while (1) { msg_return_t r; #ifdef MOSX request->msgh_size = sizeof(request_buf); request->msgh_local_port = service_port; r = msg_receive(request, MSG_OPTION_NONE | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0), 0); #else MOSX request->msg_size = sizeof(request_buf); request->msg_local_port = service_port; r = msg_receive(request, MSG_OPTION_NONE, 0); #endif if (r == RCV_SUCCESS) { extern boolean_t ipconfig_server(msg_header_t *, msg_header_t *); read_trailer(request); if (ipconfig_server(request, reply)) { r = msg_send(reply, MSG_OPTION_NONE, 0); if (r != SEND_SUCCESS) my_log(LOG_INFO, "msg_send: %s", mach_error_string(r)); } } else { #ifdef MOSX my_log(LOG_INFO, "msg_receive: %s (0x%x)", mach_error_string(r), r); if (r == MACH_RCV_INVALID_NAME) { break; /* out of while */ } #else MOSX my_log(LOG_INFO, "msg_receive: %s (%d)", mach_error_string(r), r); if (r == RCV_INVALID_PORT) { break; /* out of while */ } #endif MOSX } } } #endif 0 boolean_t server_active() { boolean_t active = FALSE; port_t server; kern_return_t status; status = ipconfig_server_port(&server, &active); if (active != FALSE) return (TRUE); return (FALSE); } static CFMachPortRef ipconfigd_port; static void S_ipconfig_server(CFMachPortRef port, void *msg, CFIndex size, void *info) { msg_header_t * request = (msg_header_t *)msg; msg_header_t * reply = (msg_header_t *)reply_buf; msg_return_t r; extern boolean_t ipconfig_server(msg_header_t *, msg_header_t *); read_trailer(request); if (ipconfig_server(request, reply)) { r = msg_send(reply, MSG_OPTION_NONE, 0); if (r != SEND_SUCCESS) my_log(LOG_INFO, "msg_send: %s", mach_error_string(r)); } return; } void server_init() { CFRunLoopSourceRef rls; boolean_t active; kern_return_t status; active = FALSE; status = bootstrap_status(bootstrap_port, IPCONFIG_SERVER, &active); switch (status) { case BOOTSTRAP_SUCCESS : if (active) { fprintf(stderr, "\"%s\" is currently active.\n", IPCONFIG_SERVER); return; } break; case BOOTSTRAP_UNKNOWN_SERVICE : break; default : fprintf(stderr, "bootstrap_status(): %s\n", mach_error_string(status)); return; break; } ipconfigd_port = CFMachPortCreate(NULL, S_ipconfig_server, NULL, NULL); rls = CFMachPortCreateRunLoopSource(NULL, ipconfigd_port, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); status = bootstrap_register(bootstrap_port, IPCONFIG_SERVER, CFMachPortGetPort(ipconfigd_port)); if (status != BOOTSTRAP_SUCCESS) { mach_error("bootstrap_register", status); } return; }