1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** NAME 79** 80** npnaf_bsd 81** 82** FACILITY: 83** 84** Remote Procedure Call (RPC) 85** 86** ABSTRACT: 87** 88** This module contains routines specific to the Internet Protocol, 89** the Internet Network Address Family extension service, and the 90** Linux. 91** 92** - taken from npnaf_bsd.c 93** 94** 95** 96*/ 97 98#include <commonp.h> 99#include <com.h> 100#include <comnaf.h> 101#include <comsoc.h> 102#include <npnaf.h> 103 104#include <sys/ioctl.h> 105#include <ctype.h> 106#include <stddef.h> 107 108 109/*********************************************************************** 110 * 111 * Internal prototypes and typedefs. 112 */ 113 114#ifndef NO_SPRINTF 115# define RPC__NP_NETWORK_SPRINTF sprintf 116#else 117# define RPC__NP_NETWORK_SPRINTF rpc__np_network_sprintf 118#endif 119 120 121/* 122**++ 123** 124** ROUTINE NAME: rpc__np_init_local_addr_vec 125** 126** SCOPE: PRIVATE - declared in ipnaf.h 127** 128** DESCRIPTION: 129** 130** Initialize the local address vectors. 131** 132** 133** INPUTS: none 134** 135** INPUTS/OUTPUTS: none 136** 137** OUTPUTS: 138** 139** status A value indicating the status of the routine. 140** 141** IMPLICIT INPUTS: none 142** 143** IMPLICIT OUTPUTS: none 144** 145** FUNCTION VALUE: none 146** 147** SIDE EFFECTS: 148** 149** Update local_np_addr_vec 150** 151**-- 152**/ 153 154PRIVATE void rpc__np_init_local_addr_vec 155( 156 unsigned32 *status 157) 158{ 159 CODING_ERROR (status); 160 161 *status = rpc_s_ok; 162 return; 163} 164 165/* 166**++ 167** 168** ROUTINE NAME: rpc__np_desc_inq_addr 169** 170** SCOPE: PRIVATE - declared in npnaf.h 171** 172** DESCRIPTION: 173** 174** Receive a socket descriptor which is queried to obtain family, endpoint 175** and network address. If this information appears valid for an IP 176** address, space is allocated for an RPC address which is initialized 177** with the information obtained from the socket. The address indicating 178** the created RPC address is returned in rpc_addr. 179** 180** INPUTS: 181** 182** protseq_id Protocol Sequence ID representing a particular 183** Network Address Family, its Transport Protocol, 184** and type. 185** 186** desc Descriptor, indicating a socket that has been 187** created on the local operating platform. 188** 189** INPUTS/OUTPUTS: none 190** 191** OUTPUTS: 192** 193** rpc_addr_vec 194** 195** status A value indicating the status of the routine. 196** 197** rpc_s_ok The call was successful. 198** 199** rpc_s_no_memory Call to malloc failed to allocate memory. 200** 201** rpc_s_cant_inq_socket Attempt to get info about socket failed. 202** 203** Any of the RPC Protocol Service status codes. 204** 205** IMPLICIT INPUTS: none 206** 207** IMPLICIT OUTPUTS: none 208** 209** FUNCTION VALUE: none 210** 211** SIDE EFFECTS: none 212** 213**-- 214**/ 215 216PRIVATE void rpc__np_desc_inq_addr 217( 218 rpc_protseq_id_t protseq_id, 219 rpc_socket_t sock, 220 rpc_addr_vector_p_t *rpc_addr_vec, 221 unsigned32 *status 222) 223{ 224 rpc_np_addr_p_t np_addr; 225 rpc_np_addr_t loc_np_addr; 226 int err = 0; 227 228 CODING_ERROR (status); 229 230 memset (&loc_np_addr, 0, sizeof(rpc_np_addr_t)); 231 232 loc_np_addr.len = sizeof(loc_np_addr) - offsetof(rpc_np_addr_t, sa); 233 234 /* 235 * Do a "getsockname" into a local IP RPC address. If the network 236 * address part of the result is non-zero, then the socket must be 237 * bound to a particular IP address and we can just return a RPC 238 * address vector with that one address (and endpoint) in it. 239 * Otherwise, we have to enumerate over all the local network 240 * interfaces the local host has and construct an RPC address for 241 * each one of them. 242 */ 243 244 err = rpc__socket_inq_endpoint(sock, (rpc_addr_p_t) &loc_np_addr); 245 246 if (err) 247 { 248 *status = -1; 249 return; 250 } 251 252 RPC_MEM_ALLOC ( 253 np_addr, 254 rpc_np_addr_p_t, 255 sizeof (rpc_np_addr_t), 256 RPC_C_MEM_RPC_ADDR, 257 RPC_C_MEM_WAITOK); 258 259 if (np_addr == NULL) 260 { 261 *status = rpc_s_no_memory; 262 return; 263 } 264 265 RPC_MEM_ALLOC ( 266 *rpc_addr_vec, 267 rpc_addr_vector_p_t, 268 sizeof **rpc_addr_vec, 269 RPC_C_MEM_RPC_ADDR_VEC, 270 RPC_C_MEM_WAITOK); 271 272 if (*rpc_addr_vec == NULL) 273 { 274 RPC_MEM_FREE (np_addr, RPC_C_MEM_RPC_ADDR); 275 *status = rpc_s_no_memory; 276 return; 277 } 278 279 memset(np_addr, 0, sizeof(rpc_np_addr_t)); 280 np_addr->rpc_protseq_id = protseq_id; 281 np_addr->len = sizeof (struct sockaddr_un); 282 np_addr->sa = loc_np_addr.sa; 283 284 /* 285 * Force the address family to AF_UNIX as getsockname() 286 * does not work for UNIX domain sockets on all platforms 287 */ 288 np_addr->sa.sun_family = AF_UNIX; 289 290 if (np_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 291 { 292 /* 293 * Assume that named pipes are unix domain sockets where the 294 * socket name is the same as the endpoint name. Trim the 295 * leading path components and prefix "\\PIPE\\" to make it 296 * into a names pipe endpoint. 297 */ 298 struct sockaddr_un tmp = np_addr->sa; 299 const char * last; 300 301 if (tmp.sun_path[0] != '\\') { 302 last = strrchr(tmp.sun_path, '/'); 303 if (!last) { 304 RPC_MEM_FREE (np_addr, RPC_C_MEM_RPC_ADDR); 305 *status = rpc_s_no_addrs; 306 return; 307 } 308 snprintf(np_addr->sa.sun_path, sizeof(np_addr->sa.sun_path), 309 "\\PIPE\\%s", last + 1); 310 } 311 else { 312 snprintf(np_addr->sa.sun_path, sizeof(np_addr->sa.sun_path), "%s", tmp.sun_path); 313 } 314 } 315 316 (*rpc_addr_vec)->len = 1; 317 (*rpc_addr_vec)->addrs[0] = (rpc_addr_p_t) np_addr; 318 319 *status = rpc_s_ok; 320 return; 321} 322 323/* 324**++ 325** 326** ROUTINE NAME: rpc__np_get_broadcast 327** 328** SCOPE: PRIVATE - EPV declared in npnaf.h 329** 330** DESCRIPTION: 331** 332** Return a vector of RPC addresses that represent all the address 333** required so that sending on all of them results in broadcasting on 334** all the local network interfaces. 335** 336** 337** INPUTS: 338** 339** naf_id Network Address Family ID serves 340** as index into EPV for IP routines. 341** 342** rpc_protseq_id 343** 344** INPUTS/OUTPUTS: none 345** 346** OUTPUTS: 347** 348** rpc_addr_vec 349** 350** status A value indicating the status of the routine. 351** 352** IMPLICIT INPUTS: none 353** 354** IMPLICIT OUTPUTS: none 355** 356** FUNCTION VALUE: none 357** 358** SIDE EFFECTS: none 359** 360**-- 361**/ 362 363PRIVATE void rpc__np_get_broadcast 364( 365 rpc_naf_id_t naf_id ATTRIBUTE_UNUSED, 366 rpc_protseq_id_t protseq_id ATTRIBUTE_UNUSED, 367 rpc_addr_vector_p_t *rpc_addr_vec, 368 unsigned32 *status 369) 370{ 371 naf_id = 0; 372 rpc_addr_vec = NULL; 373 374 CODING_ERROR (status); 375 376 *status = rpc_s_cant_inq_socket; 377 return; 378} 379/* 380**++ 381** 382** ROUTINE NAME: rpc__np_is_local_network 383** 384** SCOPE: PRIVATE - declared in npnaf.h 385** 386** DESCRIPTION: 387** 388** Return a boolean value to indicate if the given RPC address is on 389** the same IP subnet. 390** 391** 392** INPUTS: 393** 394** rpc_addr The address that forms the path of interest 395** 396** INPUTS/OUTPUTS: none 397** 398** OUTPUTS: 399** 400** status A value indicating the status of the routine. 401** 402** IMPLICIT INPUTS: none 403** 404** IMPLICIT OUTPUTS: none 405** 406** FUNCTION VALUE: 407** 408** result true => the address is on the same subnet. 409** false => not. 410** 411** SIDE EFFECTS: none 412** 413**-- 414**/ 415PRIVATE boolean32 rpc__np_is_local_network 416( 417 rpc_addr_p_t rpc_addr, 418 unsigned32 *status 419) 420{ 421 CODING_ERROR (status); 422 423 if (rpc_addr == NULL) 424 { 425 *status = rpc_s_invalid_arg; 426 return false; 427 } 428 429 *status = rpc_s_ok; 430 431 return true; 432} 433 434/* 435**++ 436** 437** ROUTINE NAME: rpc__np_is_local_addr 438** 439** SCOPE: PRIVATE - declared in npnaf.h 440** 441** DESCRIPTION: 442** 443** Return a boolean value to indicate if the given RPC address is the 444** the local IP address. 445** 446** 447** INPUTS: 448** 449** rpc_addr The address that forms the path of interest 450** 451** INPUTS/OUTPUTS: none 452** 453** OUTPUTS: 454** 455** status A value indicating the status of the routine. 456** 457** IMPLICIT INPUTS: none 458** 459** IMPLICIT OUTPUTS: none 460** 461** FUNCTION VALUE: 462** 463** result true => the address is local. 464** false => not. 465** 466** SIDE EFFECTS: none 467** 468**-- 469**/ 470 471PRIVATE boolean32 rpc__np_is_local_addr 472( 473 rpc_addr_p_t rpc_addr, 474 unsigned32 *status 475) 476{ 477 CODING_ERROR (status); 478 479 if (rpc_addr == NULL) 480 { 481 *status = rpc_s_invalid_arg; 482 return false; 483 } 484 485 *status = rpc_s_ok; 486 487 return true; 488} 489