1/* 2 * Copyright (c) 2010-2011 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** 79** NAME 80** 81** npnaf.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** This module contains routines specific to the Internet Protocol 90** and the Internet Network Address Family extension service. 91** An initialization routine is provided to be called at RPC 92** initialization time provided, the Internet Protocol is supported 93** on the local host platform. The remaining routines are entered 94** through an Entry Point Vector specific to the Internet Protocol. 95** 96** 97*/ 98 99#include <commonp.h> 100#include <com.h> 101#include <comnaf.h> 102#include <npnaf.h> 103#include <comsoc_smb.h> 104#include <comsoc_bsd.h> 105#include <ctype.h> 106#include <sys/param.h> 107#include <stddef.h> 108 109 110/*********************************************************************** 111 * 112 * Macros for sprint/scanf substitutes. 113 */ 114 115#ifndef NO_SSCANF 116# define RPC__NP_ENDPOINT_SSCANF sscanf 117#else 118# define RPC__NP_ENDPOINT_SSCANF rpc__np_endpoint_sscanf 119#endif 120 121#ifndef NO_SPRINTF 122# define RPC__NP_ENDPOINT_SPRINTF sprintf 123# define RPC__NP_NETWORK_SPRINTF sprintf 124#else 125# define RPC__NP_ENDPOINT_SPRINTF rpc__np_endpoint_sprintf 126# define RPC__NP_NETWORK_SPRINTF rpc__np_network_sprintf 127#endif 128 129 130/*********************************************************************** 131 * 132 * Routine Prototypes for the Internet Extension service routines. 133 */ 134 135INTERNAL void addr_alloc ( 136 rpc_protseq_id_t /*rpc_protseq_id*/, 137 rpc_naf_id_t /*naf_id*/, 138 unsigned_char_p_t /*endpoint*/, 139 unsigned_char_p_t /*netaddr*/, 140 unsigned_char_p_t /*network_options*/, 141 rpc_addr_p_t * /*rpc_addr*/, 142 unsigned32 * /*status*/ 143 ); 144 145INTERNAL void addr_copy ( 146 rpc_addr_p_t /*srpc_addr*/, 147 rpc_addr_p_t * /*drpc_addr*/, 148 unsigned32 * /*status*/ 149 ); 150 151INTERNAL void addr_free ( 152 rpc_addr_p_t * /*rpc_addr*/, 153 unsigned32 * /*status*/ 154 ); 155 156INTERNAL void addr_set_endpoint ( 157 unsigned_char_p_t /*endpoint*/, 158 rpc_addr_p_t * /*rpc_addr*/, 159 unsigned32 * /*status*/ 160 ); 161 162INTERNAL void addr_inq_endpoint ( 163 rpc_addr_p_t /*rpc_addr*/, 164 unsigned_char_t ** /*endpoint*/, 165 unsigned32 * /*status*/ 166 ); 167 168INTERNAL void addr_set_netaddr ( 169 unsigned_char_p_t /*netaddr*/, 170 rpc_addr_p_t * /*rpc_addr*/, 171 unsigned32 * /*status*/ 172 ); 173 174INTERNAL void addr_inq_netaddr ( 175 rpc_addr_p_t /*rpc_addr*/, 176 unsigned_char_t ** /*netaddr*/, 177 unsigned32 * /*status*/ 178 ); 179 180INTERNAL void addr_set_options ( 181 unsigned_char_p_t /*network_options*/, 182 rpc_addr_p_t * /*rpc_addr*/, 183 unsigned32 * /*status*/ 184 ); 185 186INTERNAL void addr_inq_options ( 187 rpc_addr_p_t /*rpc_addr*/, 188 unsigned_char_t ** /*network_options*/, 189 unsigned32 * /*status*/ 190 ); 191 192INTERNAL void desc_inq_network ( 193 rpc_socket_t /*desc*/, 194 rpc_network_if_id_t * /*socket_type*/, 195 rpc_network_protocol_id_t * /*protocol_id*/, 196 unsigned32 * /*status*/ 197 ); 198 199INTERNAL void inq_max_tsdu ( 200 rpc_naf_id_t /*naf_id*/, 201 rpc_network_if_id_t /*iftype*/, 202 rpc_network_protocol_id_t /*protocol*/, 203 unsigned32 * /*max_tsdu*/, 204 unsigned32 * /*status*/ 205 ); 206 207INTERNAL boolean addr_compare ( 208 rpc_addr_p_t /*addr1*/, 209 rpc_addr_p_t /*addr2*/, 210 unsigned32 * /*status*/ 211 ); 212 213INTERNAL void inq_max_pth_unfrag_tpdu ( 214 rpc_addr_p_t /*rpc_addr*/, 215 rpc_network_if_id_t /*iftype*/, 216 rpc_network_protocol_id_t /*protocol*/, 217 unsigned32 * /*max_tpdu*/, 218 unsigned32 * /*status*/ 219 ); 220 221INTERNAL void inq_max_loc_unfrag_tpdu ( 222 rpc_naf_id_t /*naf_id*/, 223 rpc_network_if_id_t /*iftype*/, 224 rpc_network_protocol_id_t /*protocol*/, 225 unsigned32 * /*max_tpdu*/, 226 unsigned32 * /*status*/ 227 ); 228 229INTERNAL void set_pkt_nodelay ( 230 rpc_socket_t /*desc*/, 231 unsigned32 * /*status*/ 232 ); 233 234INTERNAL boolean is_connect_closed ( 235 rpc_socket_t /*desc*/, 236 unsigned32 * /*status*/ 237 ); 238 239INTERNAL void tower_flrs_from_addr ( 240 rpc_addr_p_t /*rpc_addr*/, 241 twr_p_t * /*lower_flrs*/, 242 unsigned32 * /*status*/ 243 ); 244 245INTERNAL void tower_flrs_to_addr ( 246 byte_p_t /*tower_octet_string*/, 247 rpc_addr_p_t * /*rpc_addr*/, 248 unsigned32 * /*status*/ 249 ); 250 251INTERNAL void desc_inq_peer_addr ( 252 rpc_protseq_id_t /*protseq_id*/, 253 rpc_socket_t /*desc*/, 254 rpc_addr_p_t * /*rpc_addr*/, 255 unsigned32 * /*status*/ 256 ); 257 258INTERNAL void set_port_restriction ( 259 rpc_protseq_id_t /*protseq_id*/, 260 unsigned32 /*n_elements*/, 261 unsigned_char_p_t * /*first_port_name_list*/, 262 unsigned_char_p_t * /*last_port_name_list*/, 263 unsigned32 * /*status*/ 264 ); 265 266INTERNAL void get_next_restricted_port ( 267 rpc_protseq_id_t /*protseq_id*/, 268 unsigned_char_p_t * /*port_name*/, 269 unsigned32 * /*status*/ 270 ); 271 272INTERNAL void inq_max_frag_size ( 273 rpc_addr_p_t /*rpc_addr*/, 274 unsigned32 * /*max_frag_size*/, 275 unsigned32 * /*status*/ 276 ); 277 278 279/* 280**++ 281** 282** ROUTINE NAME: rpc__np_init 283** 284** SCOPE: PRIVATE - EPV declared in npnaf.h 285** 286** DESCRIPTION: 287** 288** Named Pipe Family Initialization routine, rpc__np_init, is 289** calld only once, by the Communications Service initialization 290** procedure, at the time RPC is initialized. If the Communications 291** Service initialization determines that the Internet protocol 292** family is supported on the local host platform it will call this 293** initialization routine. It is responsible for all Internet 294** specific initialization for the current RPC. It will place in 295** Network Address Family Table, a pointer to the Internet family Entry 296** Point Vector. Afterward all calls to the IP extension service 297** routines will be vectored through this EPV. 298** 299** INPUTS: none 300** 301** INPUTS/OUTPUTS: 302** 303** naf_epv The address of a pointer in the Network Address Family 304** Table whre the pointer to the Entry Point Vectorto 305** the NP service routines is inserted by this routine. 306** 307** OUTPUTS: 308** 309** status A value indicating the status of the routine. 310** 311** rpc_s_ok The call was successful. 312** 313** Any of the RPC Protocol Service status codes. 314** 315** IMPLICIT INPUTS: none 316** 317** IMPLICIT OUTPUTS: none 318** 319** FUNCTION VALUE: none 320** 321** SIDE EFFECTS: none 322** 323**-- 324**/ 325 326#if !NAF_NP_STATIC 327#include <comp.h> 328PRIVATE void rpc__np_naf_init_func(void) 329{ 330 static rpc_naf_id_elt_t naf[1] = { 331 { 332 rpc__np_init, 333 RPC_C_NAF_ID_UXD, 334 RPC_C_NETWORK_IF_ID_STREAM, 335 NULL 336 } 337 }; 338 /* 339 * Unfortunately we can only have one NAF per module, so 340 * we need to handle ncacn_np and ncalrpc within the same 341 * code. The only difference server-side is the path naming 342 * semantics, the protocol towers, and the passing of security 343 * descriptors. 344 */ 345 static rpc_tower_prot_ids_t prot_ids[] = { 346 { rpc_c_protseq_id_ncacn_np, 3, 347 { {0x0B, { 0, 0, 0, 0, 0, {0} }}, /* Connection-oriented */ 348 {0x0F, { 0, 0, 0, 0, 0, {0} }}, /* SMB Named Pipes */ 349 {0x11, { 0, 0, 0, 0, 0, {0} }}, /* NetBIOS host */ 350 {0x00, { 0, 0, 0, 0, 0, {0} }} } }, 351 { rpc_c_protseq_id_ncalrpc, 2, 352 { {0x0B, { 0, 0, 0, 0, 0, {0} }}, /* Connection-oriented */ 353 {0x20, { 0, 0, 0, 0, 0, {0} }}, /* socket pathname */ 354 {0x00, { 0, 0, 0, 0, 0, {0} }} } } 355 }; 356 static rpc_protseq_id_elt_t seq_ids[] = { 357 { /* Connection-RPC / NP / NB */ 358 0, 359 0, /* Does not use endpoint mapper */ 360 rpc_c_protseq_id_ncacn_np, 361 RPC_C_PROTOCOL_ID_NCACN, 362 RPC_C_NAF_ID_UXD, 363 RPC_C_NETWORK_PROTOCOL_ID_NP, 364 RPC_C_NETWORK_IF_ID_STREAM, 365 RPC_PROTSEQ_NCACN_NP, 366 (rpc_port_restriction_list_p_t) NULL, 367 &rpc_g_smb_socket_vtbl 368 }, 369 { /* Connection-RPC / UXD */ 370 0, 371 0, /* Does not use endpoint mapper */ 372 rpc_c_protseq_id_ncalrpc, 373 RPC_C_PROTOCOL_ID_NCACN, 374 RPC_C_NAF_ID_UXD, 375 RPC_C_NETWORK_PROTOCOL_ID_UXD, 376 RPC_C_NETWORK_IF_ID_STREAM, 377 RPC_PROTSEQ_NCALRPC, 378 (rpc_port_restriction_list_p_t) NULL, 379 &rpc_g_bsd_socket_vtbl 380 } 381 382 }; 383 rpc__register_protseq(seq_ids, 384 sizeof(seq_ids)/sizeof(seq_ids[0])); 385 rpc__register_tower_prot_id(prot_ids, 386 sizeof(prot_ids)/sizeof(prot_ids[0])); 387 rpc__register_naf_id(naf, 1); 388} 389#endif 390 391PRIVATE void rpc__np_init 392( 393 rpc_naf_epv_p_t *naf_epv, 394 unsigned32 *status 395) 396{ 397 /* 398 * The Internal Entry Point Vectors for the Internet Protocol Family 399 * Extension service routines. At RPC startup time, the IP init routine, 400 * rpc__np_init, is responsible for inserting a pointer to this EPV into 401 * the Network Address Family Table. Afterward, all calls to the IP 402 * Extension Service are vectored through these EPVs. 403 */ 404 405 static const rpc_naf_epv_t rpc_np_epv = 406 { 407 .naf_addr_alloc = addr_alloc, 408 .naf_addr_copy = addr_copy, 409 .naf_addr_free = addr_free, 410 .naf_addr_set_endpoint = addr_set_endpoint, 411 .naf_addr_inq_endpoint = addr_inq_endpoint, 412 .naf_addr_set_netaddr = addr_set_netaddr, 413 .naf_addr_inq_netaddr = addr_inq_netaddr, 414 .naf_addr_set_options = addr_set_options, 415 .naf_addr_inq_options = addr_inq_options, 416 .naf_desc_inq_addr = rpc__np_desc_inq_addr, 417 .naf_desc_inq_network = desc_inq_network, 418 .naf_inq_max_tsdu = inq_max_tsdu, 419 .naf_get_broadcast = rpc__np_get_broadcast, 420 .naf_addr_compare = addr_compare, 421 .naf_inq_max_pth_unfrg_tpdu = inq_max_pth_unfrag_tpdu, 422 .naf_inq_max_loc_unfrg_tpdu = inq_max_loc_unfrag_tpdu, 423 .naf_set_pkt_nodelay = set_pkt_nodelay, 424 .naf_is_connect_closed = is_connect_closed, 425 .naf_tower_flrs_from_addr = tower_flrs_from_addr, 426 .naf_tower_flrs_to_addr = tower_flrs_to_addr, 427 .naf_desc_inq_peer_addr = desc_inq_peer_addr, 428 .naf_set_port_restriction = set_port_restriction, 429 .naf_get_next_restricted_port = get_next_restricted_port, 430 .naf_inq_max_frag_size = inq_max_frag_size 431 }; 432 unsigned32 lstatus; 433 434 rpc__np_init_local_addr_vec (&lstatus); 435 436 /* 437 * place the address of EPV into Network Address Family Table 438 */ 439 *naf_epv = &rpc_np_epv; 440 441 *status = rpc_s_ok; 442} 443 444/* 445**++ 446** 447** ROUTINE NAME: addr_alloc 448** 449** SCOPE: INTERNAL - declared locally 450** 451** DESCRIPTION: 452** 453** Create a copy of an RPC address. Allocate memory for a variable 454** length RPC address, for the NP service. Insert the Internet 455** address and endpoint along with the overall length of the allocated 456** memory, together with any additional parameters required by the IP 457** service. 458** 459** INPUTS: 460** 461** rpc_protseq_id Protocol Sequence ID representing an IP Network 462** Address Family, its Transport Protocol, and type. 463** 464** naf_id Network Address Family ID serves as index into 465** EPV for IP routines. 466** 467** endpoint String containing endpoint to insert into newly 468** allocated RPC address. 469** 470** netaddr String containing Internet format network 471** address to be inserted in RPC addr. 472** 473** network_options String containing options to be placed in 474** RPC address. - Not used by NP service. 475** 476** INPUTS/OUTPUTS: 477** 478** rpc_addr The address of a pointer to an RPC address - 479** returned with the address of the memory 480** allocated by this routine. 481** 482** OUTPUTS: 483** 484** status A value indicating the status of the routine. 485** 486** rpc_s_ok The call was successful. 487** 488** rpc_s_no_memory Call to malloc failed to allocate memory 489** 490** Any of the RPC Protocol Service status codes. 491** 492** IMPLICIT INPUTS: none 493** 494** IMPLICIT OUTPUTS: none 495** 496** FUNCTION VALUE: none 497** 498** SIDE EFFECTS: none 499** 500** 501**-- 502**/ 503 504INTERNAL void addr_alloc 505( 506 rpc_protseq_id_t rpc_protseq_id, 507 rpc_naf_id_t naf_id, 508 unsigned_char_p_t endpoint, 509 unsigned_char_p_t netaddr, 510 unsigned_char_p_t network_options ATTRIBUTE_UNUSED, 511 rpc_addr_p_t *rpc_addr, 512 unsigned32 *status 513) 514{ 515 CODING_ERROR (status); 516 517 /* 518 * allocate memory for the new RPC address 519 */ 520 521 RPC_MEM_ALLOC ( 522 *rpc_addr, 523 rpc_addr_p_t, 524 sizeof (rpc_np_addr_t), 525 RPC_C_MEM_RPC_ADDR, 526 RPC_C_MEM_WAITOK); 527 528 if (*rpc_addr == NULL) 529 { 530 *status = rpc_s_no_memory; 531 return; 532 } 533 534 /* 535 * zero allocated memory 536 */ 537 memset( *rpc_addr, 0, sizeof (rpc_np_addr_t)); 538 539 assert(RPC_C_PATH_NP_MAX <= sizeof(((rpc_np_addr_p_t) *rpc_addr)->sa.sun_path)); 540 541 /* 542 * insert id, length, family into rpc address 543 */ 544 (*rpc_addr)->rpc_protseq_id = rpc_protseq_id; 545 (*rpc_addr)->len = sizeof (struct sockaddr_un); 546 (*rpc_addr)->sa.family = naf_id; 547 548 /* 549 * set the endpoint in the RPC addr 550 */ 551 addr_set_endpoint (endpoint, rpc_addr, status); 552 if (*status != rpc_s_ok) return; 553 554 /* 555 * set the network address in the RPC addr 556 */ 557 addr_set_netaddr (netaddr, rpc_addr, status); 558 if (*status != rpc_s_ok) return; 559 560 *status = rpc_s_ok; 561} 562 563/* 564**++ 565** 566** ROUTINE NAME: addr_copy 567** 568** SCOPE: INTERNAL - declared locally 569** 570** DESCRIPTION: 571** 572** Obtain the length from the source RPC address. Allocate memory for a 573** new, destination RPC address. Do a byte copy from the surce address 574** to the destination address. 575** 576** INPUTS: 577** 578** src_rpc_addr The address of a pointer to an RPC address to be 579** copied. It must be the correct format for Internet 580** Protocol. 581** 582** INPUTS/OUTPUTS: 583** 584** dst_rpc_addr The address of a pointer to an RPC address -returned 585** with the address of the memory allocated by 586** this routine. 587** 588** OUTPUTS: 589** 590** status A value indicating the status of the routine. 591** 592** rpc_s_ok The call was successful. 593** 594** rpc_s_no_memory Call to malloc failed to allocate memory 595** 596** rpc_s_invalid_naf_id Source RPC address appeared invalid 597** 598** 599** IMPLICIT INPUTS: 600** 601** A check is performed on the source RPC address before malloc. It 602** must be the IP family. 603** 604** IMPLICIT OUTPUTS: none 605** 606** FUNCTION VALUE: none 607** 608** SIDE EFFECTS: 609** 610** In the event, the addres of a of memory segment contained in 611** rpc_addr, is not valid or the length isn't as long as is 612** indicated, a memory fault may result. 613** 614**-- 615**/ 616 617INTERNAL void addr_copy 618( 619 rpc_addr_p_t src_rpc_addr, 620 rpc_addr_p_t *dst_rpc_addr, 621 unsigned32 *status 622) 623{ 624 CODING_ERROR (status); 625 626 /* 627 * if the source RPC address looks valid - IP family ok 628 */ 629 if (src_rpc_addr->sa.family == RPC_C_NAF_ID_UXD) 630 { 631 /* 632 * allocate memory for the new RPC address 633 */ 634 RPC_MEM_ALLOC ( 635 *dst_rpc_addr, 636 rpc_addr_p_t, 637 sizeof (rpc_np_addr_t), 638 RPC_C_MEM_RPC_ADDR, 639 RPC_C_MEM_WAITOK); 640 641 if (*dst_rpc_addr == NULL) 642 { 643 *status = rpc_s_no_memory; 644 return; 645 } 646 647 /* 648 * Copy source rpc address to destination rpc address 649 */ 650 /* b_c_o_p_y ((unsigned8 *) src_rpc_addr, (unsigned8 *) *dst_rpc_addr, 651 sizeof (rpc_np_addr_t));*/ 652 653 memmove( *dst_rpc_addr, src_rpc_addr, sizeof (rpc_np_addr_t)); 654 655 *status = rpc_s_ok; 656 return; 657 } 658 659 *status = rpc_s_invalid_naf_id; 660} 661 662/* 663**++ 664** 665** ROUTINE NAME: addr_free 666** 667** SCOPE: INTERNAL - declared locally 668** 669** DESCRIPTION: 670** 671** Free the memory for the RPC address pointed to by the argument 672** address pointer rpc_addr. Null the address pointer. The memory 673** must have been previously allocated by RPC_MEM_ALLC. 674** 675** INPUTS: none 676** 677** INPUTS/OUTPUTS: 678** 679** rpc_addr The address of a pointer to an RPC address -returned 680** with a NULL value. 681** 682** OUTPUTS: 683** 684** status A value indicating the status of the routine. 685** 686** rpc_s_ok The call was successful. 687** 688** 689** IMPLICIT INPUTS: none 690** 691** IMPLICIT OUTPUTS: none 692** 693** FUNCTION VALUE: none 694** 695** SIDE EFFECTS: 696** In the event, the segment of memory refered to by pointer 697** rpc_addr, is allocated by means other than RPC_MEM_ALLOC, 698** unpredictable results will occur when this routine is called. 699**-- 700**/ 701 702INTERNAL void addr_free 703( 704 rpc_addr_p_t *rpc_addr, 705 unsigned32 *status 706) 707{ 708 CODING_ERROR (status); 709 710 /* 711 * free memory of RPC addr 712 */ 713 RPC_MEM_FREE (*rpc_addr, RPC_C_MEM_RPC_ADDR); 714 715 /* 716 * indicate that the rpc_addr is now empty 717 */ 718 *rpc_addr = NULL; 719 720 *status = rpc_s_ok; 721} 722 723/* 724**++ 725** 726** ROUTINE NAME: addr_set_endpoint 727** 728** SCOPE: INTERNAL - declared locally 729** 730** DESCRIPTION: 731** 732** Receive the null terminated ascii character string, rpc_endpoint 733** and convert to the Internet Protocol byte order format. Insert 734** into the RPC address, pointed to by argument rpc_addr. The only 735** acceptible endpoint for IP is numeric asci string, or a NULL string. 736** 737** INPUTS: 738** 739** endpoint String containing endpoint to insert into RPC address. 740** For IP must contain an ASCII numeric value, or NULL. 741** 742** INPUTS/OUTPUTS: 743** 744** rpc_addr The address of a pointer to an RPC address where 745** the endpoint is to be inserted. 746** 747** OUTPUTS: 748** 749** status A value indicating the status of the routine. 750** 751** rpc_s_ok The call was successful. 752** 753** rpc_s_invalid_naf_id Argument, endpoint contains an 754** unauthorized pointer value. 755** rpc_s_invalid_endpoint_format Endpoint Argument can not be 756** converted (not numeric). 757** 758** IMPLICIT INPUTS: 759** 760** A NULL, (first byte NULL), endpoint string is an indicator to 761** the routine to delete the endpoint from the RPC address. indicated. 762** 763** IMPLICIT OUTPUTS: none 764** 765** FUNCTION VALUE: none 766** 767** SIDE EFFECTS: none 768** 769**-- 770**/ 771 772INTERNAL void addr_set_endpoint 773( 774 unsigned_char_p_t endpoint, 775 rpc_addr_p_t *rpc_addr, 776 unsigned32 *status 777) 778{ 779 rpc_np_addr_p_t np_addr = (rpc_np_addr_p_t) *rpc_addr; 780 unsigned_char_p_t p; 781 size_t req_len; 782 const char * pipe_dir; 783 784 CODING_ERROR (status); 785 786 /* 787 * check to see if this is a request to remove the endpoint 788 */ 789 if (endpoint == NULL || strlen ((char *) endpoint) == 0) 790 { 791 np_addr->sa.sun_path[0] = '\0'; 792 *status = rpc_s_ok; 793 return; 794 } 795 796 switch (np_addr->rpc_protseq_id) 797 { 798 case rpc_c_protseq_id_ncacn_np: 799 pipe_dir = RPC_C_NP_DIR; 800 801 if (!rpc__np_is_valid_endpoint(endpoint, status)) 802 { 803 *status = rpc_s_invalid_endpoint_format; 804 return; 805 } 806 807 break; 808 case rpc_c_protseq_id_ncalrpc: 809 pipe_dir = RPC_C_UXD_DIR; 810 break; 811 812 default: 813 *status = rpc_s_invalid_endpoint_format; 814 return; 815 } 816 817 req_len = strlen((char *)endpoint); 818 if (endpoint[0] != '/') 819 { 820 /* Relative ncalrpc path. */ 821 req_len += strlen(pipe_dir) + 1; 822 } 823 824 if (req_len >= RPC_C_ENDPOINT_NP_MAX - 1) 825 { 826 *status = rpc_s_invalid_endpoint_format; 827 return; 828 } 829 830 if (endpoint[0] != '/' && endpoint[0] != '\\') 831 snprintf(np_addr->sa.sun_path, RPC_C_ENDPOINT_NP_MAX, "%s/%s", pipe_dir, endpoint); 832 else 833 strncpy(np_addr->sa.sun_path, (char *)endpoint, req_len); 834 835 /* 836 * Convert backslashes to forward slashes to conform to 837 * UNIX filesystem convention. 838 */ 839 if (np_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 840 { 841 for (p = (unsigned char*) &np_addr->sa.sun_path[RPC_C_NP_DIR_LEN]; *p != '\0'; p++) { 842 if (*p == '\\') 843 *p = '/'; 844 } 845 } 846 847 *status = rpc_s_ok; 848} 849 850/* 851**++ 852** 853** ROUTINE NAME: addr_inq_endpoint 854** 855** SCOPE: INTERNAL - declared locally 856** 857** DESCRIPTION: 858** 859** From the RPC address indicated by arg., rpc_addr, examine the 860** endpoint. Convert the endopint value to a NULL terminated asci 861** character string to be returned in the memory segment pointed to 862** by arg., endpoint. 863** 864** INPUTS: 865** 866** rpc_addr The address of a pointer to an RPC address that 867** to be inspected. 868** 869** INPUTS/OUTPUTS: none 870** 871** 872** OUTPUTS: 873** 874** endpoint String pointer indicating where the endpoint 875** string is to be placed. 876** 877** status A value indicating the status of the routine. 878** 879** rpc_s_ok The call was successful. 880** 881** Any of the RPC Protocol Service status codes. 882** 883** IMPLICIT INPUTS: none 884** 885** IMPLICIT OUTPUTS: 886** 887** A zero length string will be returned if the RPC address contains 888** no endpoint. 889** 890** FUNCTION VALUE: none 891** 892** SIDE EFFECTS: 893** 894** CAUTION -- since this routine has no way of knowing the exact 895** length of the endpoint string which will be derived. It 896** is asumed that the caller has provided, rpc_c_endpoint_max 897** (or at least "enough") space for the endpoint string. 898**-- 899**/ 900 901INTERNAL void addr_inq_endpoint 902( 903 rpc_addr_p_t rpc_addr, 904 unsigned_char_t **endpoint, 905 unsigned32 *status 906) 907{ 908 rpc_np_addr_p_t np_addr = (rpc_np_addr_p_t) rpc_addr; 909 char *sun_path; 910 unsigned_char_t *p, *q; 911 912 CODING_ERROR (status); 913 914 sun_path = np_addr->sa.sun_path; 915 916 RPC_DBG_GPRINTF (("(addr_inq_endpoint) sun_path->%s\n", sun_path)); 917 918 /* 919 * if no endpoint present, return null string. Otherwise, 920 * return the endpoint in Internet "dot" notation. 921 */ 922 if (sun_path[0] == 0) 923 { 924 RPC_MEM_ALLOC( 925 *endpoint, 926 unsigned_char_p_t, 927 sizeof(unsigned32), /* can't stand to get just 1 byte */ 928 RPC_C_MEM_STRING, 929 RPC_C_MEM_WAITOK); 930 (*endpoint)[0] = 0; 931 } 932 else 933 { 934 RPC_MEM_ALLOC( 935 *endpoint, 936 unsigned_char_p_t, 937 RPC_C_ENDPOINT_NP_MAX, 938 RPC_C_MEM_STRING, 939 RPC_C_MEM_WAITOK); 940 if (np_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 941 { 942 if (!rpc__np_is_valid_endpoint((const unsigned_char_t *)sun_path, status)) 943 { 944 return; 945 } 946 for (p = (unsigned char*) sun_path, q = (unsigned char*) *endpoint; *p != '\0'; p++) { 947 *q++ = (*p == '/') ? '\\' : *p; 948 } 949 *q = '\0'; 950 } 951 else 952 { 953 if (strncmp(sun_path, RPC_C_NP_DIR, RPC_C_NP_DIR_LEN) != 0) 954 { 955 strlcpy((char*) *endpoint, sun_path, RPC_C_ENDPOINT_NP_MAX); 956 } 957 else 958 { 959 strlcpy((char*) *endpoint, &sun_path[RPC_C_NP_DIR_LEN + 1], RPC_C_ENDPOINT_NP_MAX); 960 } 961 } 962 } 963 964 *status = rpc_s_ok; 965} 966 967/* 968**++ 969** 970** ROUTINE NAME: addr_set_netaddr 971** 972** SCOPE: INTERNAL - declared locally 973** 974** DESCRIPTION: 975** 976** Receive the null terminated ascii character string, netaddr, 977** and convert to the Internet Protocol Network Address format. Insert 978** into the RPC address, indicated by argument rpc_addr. 979** 980** INPUTS: 981** 982** netaddr String containing network address to insert into 983** RPC address. It must contain an ASCII value in the 984** Internet dot notation, (a.b.c.d), format. 985** 986** INPUTS/OUTPUTS: 987** 988** rpc_addr The address of a pointer to an RPC address where 989** the network address is to be inserted. 990** 991** OUTPUTS: 992** 993** status A value indicating the status of the routine. 994** 995** rpc_s_ok The call was successful. 996** rpc_s_inval_net_addr Invalid IP network address string passed 997** in netaddr 998** 999** 1000** IMPLICIT INPUTS: none 1001** 1002** IMPLICIT OUTPUTS: none 1003** 1004** FUNCTION VALUE: none 1005** 1006** SIDE EFFECTS: none 1007** 1008**-- 1009**/ 1010 1011INTERNAL void addr_set_netaddr 1012( 1013 unsigned_char_p_t netaddr, 1014 rpc_addr_p_t *rpc_addr, 1015 unsigned32 *status 1016) 1017{ 1018 rpc_np_addr_p_t np_addr = (rpc_np_addr_p_t) *rpc_addr; 1019 1020 CODING_ERROR (status); 1021 1022 /* 1023 * check to see if this is a request to remove the netaddr 1024 */ 1025 if (netaddr == NULL || strlen ((char *) netaddr) == 0) 1026 { 1027 np_addr->remote_host[0] = '\0'; 1028 *status = rpc_s_ok; 1029 return; 1030 } 1031 1032 strncpy((char*) &np_addr->remote_host, (char*) netaddr, sizeof(np_addr->remote_host) - 1); 1033 np_addr->remote_host[sizeof(np_addr->remote_host) - 1] = '\0'; 1034 1035 *status = rpc_s_ok; 1036} 1037 1038/* 1039**++ 1040** 1041** ROUTINE NAME: addr_inq_netaddr 1042** 1043** SCOPE: INTERNAL - declared locally 1044** 1045** DESCRIPTION: 1046** 1047** From the RPC address indicated by arg., rpc_addr, examine the 1048** IP network address. Convert the network address from its network 1049** format to a NULL terminated ascii character string in IP dot 1050** notation format. The character string to be returned in the 1051** memory segment pointed to by arg., netaddr. 1052** 1053** INPUTS: 1054** 1055** rpc_addr The address of a pointer to an RPC address that 1056** is to be inspected. 1057** 1058** INPUTS/OUTPUTS: 1059** 1060** 1061** OUTPUTS: 1062** 1063** netaddr String pointer indicating where the network 1064** address string is to be placed. 1065** 1066** status A value indicating the status of the routine. 1067** 1068** rpc_s_ok The call was successful. 1069** 1070** IMPLICIT INPUTS: none 1071** 1072** IMPLICIT OUTPUTS: none 1073** 1074** FUNCTION VALUE: none 1075** 1076** SIDE EFFECTS: none 1077** 1078**-- 1079**/ 1080 1081INTERNAL void addr_inq_netaddr 1082( 1083 rpc_addr_p_t rpc_addr, 1084 unsigned_char_t **p_netaddr, 1085 unsigned32 *status 1086) 1087{ 1088 rpc_np_addr_p_t np_addr = (rpc_np_addr_p_t) rpc_addr; 1089 unsigned_char_p_t netaddr; 1090 size_t addr_length = 0; 1091 1092 CODING_ERROR (status); 1093 1094 /* Note that we return an empty string if the protocol 1095 sequence is not ncacn_np */ 1096 if (np_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 1097 { 1098 addr_length = strlen(np_addr->remote_host); 1099 } 1100 1101 RPC_MEM_ALLOC( 1102 *p_netaddr, 1103 unsigned_char_p_t, 1104 addr_length + 1, 1105 RPC_C_MEM_STRING, 1106 RPC_C_MEM_WAITOK); 1107 if (*p_netaddr == NULL) { 1108 *status = rpc_s_no_memory; 1109 return; 1110 } 1111 netaddr = *p_netaddr; 1112 1113 memcpy(netaddr, np_addr->remote_host, addr_length); 1114 netaddr[addr_length] = 0; 1115 1116 *status = rpc_s_ok; 1117} 1118 1119/* 1120**++ 1121** 1122** ROUTINE NAME: addr_set_options 1123** 1124** SCOPE: INTERNAL - declared locally 1125** 1126** DESCRIPTION: 1127** 1128** Receive a NULL terminated network options string and insert 1129** into the RPC address indicated by art., rpc_addr. 1130** 1131** NOTE - there are no options used with the NP service this 1132** routine is here only to serve as a stub. 1133** 1134** INPUTS: 1135** 1136** options String containing network options to insert 1137** into RPC address. 1138** 1139** INPUTS/OUTPUTS: 1140** 1141** rpc_addr The address of a pointer to an RPC address where 1142** the network options strig is to be inserted. 1143** OUTPUTS: 1144** 1145** status A value indicating the status of the routine. 1146** 1147** rpc_s_ok The call was successful. 1148** 1149** IMPLICIT INPUTS: none 1150** 1151** IMPLICIT OUTPUTS: none 1152** 1153** FUNCTION VALUE: none 1154** 1155** SIDE EFFECTS: none 1156** 1157**-- 1158**/ 1159 1160INTERNAL void addr_set_options 1161( 1162 unsigned_char_p_t network_options ATTRIBUTE_UNUSED, 1163 rpc_addr_p_t *rpc_addr ATTRIBUTE_UNUSED, 1164 unsigned32 *status 1165) 1166{ 1167 *status = rpc_s_ok; 1168} 1169 1170/* 1171**++ 1172** 1173** ROUTINE NAME: addr_inq_options 1174** 1175** SCOPE: INTERNAL - declared locally 1176** 1177** DESCRIPTION: 1178** 1179** Extract the network options from the RPC address pointed to 1180** by rpc_addr and convert to a NULL terminated string placed 1181** in a buffer indicated by the options arg. 1182** 1183** NOTE - there are no options used with the NP service this 1184** routine is here only to serve as a stub. 1185** 1186** INPUTS: 1187** 1188** rpc_addr The address of a pointer to an RPC address that 1189** is to be inspected. 1190** 1191** INPUTS/OUTPUTS: none 1192** 1193** OUTPUTS: 1194** 1195** options String pointer indicating where the network 1196** options string is to be placed. 1197** 1198** 1199** status A value indicating the status of the routine. 1200** 1201** rpc_s_ok The call was successful. 1202** 1203** IMPLICIT INPUTS: none 1204** 1205** IMPLICIT OUTPUTS: none 1206** 1207** FUNCTION VALUE: none 1208** 1209** SIDE EFFECTS: none 1210** 1211**-- 1212**/ 1213 1214INTERNAL void addr_inq_options 1215( 1216 rpc_addr_p_t rpc_addr ATTRIBUTE_UNUSED, 1217 unsigned_char_t **network_options, 1218 unsigned32 *status 1219) 1220{ 1221 RPC_MEM_ALLOC( 1222 *network_options, 1223 unsigned_char_p_t, 1224 sizeof(unsigned32), /* only really need 1 byte */ 1225 RPC_C_MEM_STRING, 1226 RPC_C_MEM_WAITOK); 1227 1228 *network_options[0] = 0; 1229 *status = rpc_s_ok; 1230} 1231 1232/* 1233**++ 1234** 1235** ROUTINE NAME: inq_max_tsdu 1236** 1237** SCOPE: INTERNAL - declared locally 1238** 1239** DESCRIPTION: 1240** 1241** INPUTS: 1242** 1243** naf_id Network Address Family ID serves 1244** as index into EPV for IP routines. 1245** 1246** iftype Network interface type ID 1247** 1248** protocol Network protocol ID 1249** 1250** INPUTS/OUTPUTS: none 1251** 1252** OUTPUTS: 1253** 1254** max_tsdu 1255** 1256** status A value indicating the status of the routine. 1257** 1258** IMPLICIT INPUTS: none 1259** 1260** IMPLICIT OUTPUTS: none 1261** 1262** FUNCTION VALUE: none 1263** 1264** SIDE EFFECTS: none 1265** 1266**-- 1267**/ 1268 1269INTERNAL void inq_max_tsdu 1270( 1271 rpc_naf_id_t naf_id ATTRIBUTE_UNUSED, 1272 rpc_network_if_id_t iftype ATTRIBUTE_UNUSED, 1273 rpc_network_protocol_id_t protocol ATTRIBUTE_UNUSED, 1274 unsigned32 *max_tsdu, 1275 unsigned32 *status 1276) 1277{ 1278 *max_tsdu = RPC_C_NP_MAX_LOCAL_FRAG_SIZE; 1279 1280#ifdef DEBUG 1281 if (RPC_DBG (rpc_es_dbg_np_max_tsdu, 1)) 1282 { 1283 *max_tsdu = ((unsigned32) 1284 (rpc_g_dbg_switches[(int) rpc_es_dbg_np_max_tsdu])) * 1024; 1285 } 1286#endif 1287 1288 *status = rpc_s_ok; 1289} 1290 1291/* 1292**++ 1293** 1294** ROUTINE NAME: addr_compare 1295** 1296** SCOPE: INTERNAL - declared locally 1297** 1298** DESCRIPTION: 1299** 1300** Determine if two address are equal. 1301** 1302** INPUTS: 1303** 1304** addr1 1305** 1306** addr2 1307** 1308** INPUTS/OUTPUTS: none 1309** 1310** OUTPUTS: 1311** 1312** status A value indicating the status of the routine. 1313** 1314** IMPLICIT INPUTS: none 1315** 1316** IMPLICIT OUTPUTS: none 1317** 1318** FUNCTION VALUE: 1319** 1320** return Boolean; true if address are the same. 1321** 1322** SIDE EFFECTS: none 1323** 1324**-- 1325**/ 1326 1327INTERNAL boolean addr_compare 1328( 1329 rpc_addr_p_t addr1, 1330 rpc_addr_p_t addr2, 1331 unsigned32 *status ATTRIBUTE_UNUSED 1332) 1333{ 1334 rpc_np_addr_p_t np_addr1 = (rpc_np_addr_p_t) addr1; 1335 rpc_np_addr_p_t np_addr2 = (rpc_np_addr_p_t) addr2; 1336 1337 if (np_addr1->sa.sun_family == np_addr2->sa.sun_family && 1338 strncmp(np_addr1->sa.sun_path, 1339 np_addr2->sa.sun_path, sizeof(np_addr1->sa.sun_path)) == 0 && 1340 strncmp(np_addr1->remote_host, 1341 np_addr2->remote_host, sizeof(np_addr1->remote_host)) == 0) 1342 { 1343 return true; 1344 } 1345 else 1346 { 1347 return false; 1348 } 1349} 1350 1351 1352/* 1353**++ 1354** 1355** ROUTINE NAME: inq_max_pth_unfrag_tpdu 1356** 1357** SCOPE: INTERNAL - declared locally 1358** 1359** DESCRIPTION: 1360** 1361** INPUTS: 1362** 1363** naf_id Network Address Family ID serves 1364** as index into EPV for IP routines. 1365** 1366** iftype Network interface type ID 1367** 1368** protocol Network protocol ID 1369** 1370** INPUTS/OUTPUTS: none 1371** 1372** OUTPUTS: 1373** 1374** max_tpdu 1375** 1376** status A value indicating the status of the routine. 1377** 1378** IMPLICIT INPUTS: none 1379** 1380** IMPLICIT OUTPUTS: none 1381** 1382** FUNCTION VALUE: none 1383** 1384** SIDE EFFECTS: none 1385** 1386**-- 1387**/ 1388 1389INTERNAL void inq_max_pth_unfrag_tpdu 1390( 1391 rpc_addr_p_t rpc_addr ATTRIBUTE_UNUSED, 1392 rpc_network_if_id_t iftype ATTRIBUTE_UNUSED, 1393 rpc_network_protocol_id_t protocol ATTRIBUTE_UNUSED, 1394 unsigned32 *max_tpdu, 1395 unsigned32 *status 1396) 1397{ 1398 *max_tpdu = RPC_C_NP_MAX_LOCAL_FRAG_SIZE; 1399 1400#ifdef DEBUG 1401 if (RPC_DBG (rpc_es_dbg_np_max_pth_unfrag_tpdu, 1)) 1402 { 1403 *max_tpdu = ((unsigned32) 1404 (rpc_g_dbg_switches[(int) rpc_es_dbg_np_max_pth_unfrag_tpdu])) * 32; 1405 } 1406#endif 1407 1408 *status = rpc_s_ok; 1409} 1410 1411/* 1412**++ 1413** 1414** ROUTINE NAME: inq_max_loc_unfrag_tpdu 1415** 1416** SCOPE: INTERNAL - declared locally 1417** 1418** DESCRIPTION: 1419** 1420** INPUTS: 1421** 1422** naf_id Network Address Family ID serves 1423** as index into EPV for IP routines. 1424** 1425** iftype Network interface type ID 1426** 1427** protocol Network protocol ID 1428** 1429** INPUTS/OUTPUTS: none 1430** 1431** OUTPUTS: 1432** 1433** max_tpdu 1434** 1435** status A value indicating the status of the routine. 1436** 1437** IMPLICIT INPUTS: none 1438** 1439** IMPLICIT OUTPUTS: none 1440** 1441** FUNCTION VALUE: none 1442** 1443** SIDE EFFECTS: none 1444** 1445**-- 1446**/ 1447 1448INTERNAL void inq_max_loc_unfrag_tpdu 1449( 1450 rpc_naf_id_t naf_id ATTRIBUTE_UNUSED, 1451 rpc_network_if_id_t iftype ATTRIBUTE_UNUSED, 1452 rpc_network_protocol_id_t protocol ATTRIBUTE_UNUSED, 1453 unsigned32 *max_tpdu, 1454 unsigned32 *status 1455) 1456{ 1457 *max_tpdu = RPC_C_NP_MAX_LOCAL_FRAG_SIZE; 1458 1459#ifdef DEBUG 1460 if (RPC_DBG (rpc_es_dbg_np_max_loc_unfrag_tpdu, 1)) 1461 { 1462 *max_tpdu = ((unsigned32) 1463 (rpc_g_dbg_switches[(int) rpc_es_dbg_np_max_loc_unfrag_tpdu])) * 32; 1464 } 1465#endif 1466 1467 *status = rpc_s_ok; 1468} 1469 1470/* 1471**++ 1472** 1473** ROUTINE NAME: desc_inq_network 1474** 1475** SCOPE: INTERNAL - declared locally 1476** 1477** DESCRIPTION: 1478** 1479** This routine is responsible for "reverse-engineering" the parameters to 1480** the original socket call that was made to create the socket "desc". 1481** 1482** INPUTS: 1483** 1484** desc socket descriptor to query 1485** 1486** INPUTS/OUTPUTS: 1487** 1488** OUTPUTS: 1489** 1490** socket_type network interface type id 1491** 1492** protocol_id network protocol family id 1493** 1494** status status returned 1495** rpc_s_ok 1496** rpc_s_cant_get_if_id 1497** 1498** IMPLICIT INPUTS: none 1499** 1500** IMPLICIT OUTPUTS: none 1501** 1502** FUNCTION VALUE: none 1503** 1504** SIDE EFFECTS: none 1505** 1506**-- 1507**/ 1508 1509INTERNAL void desc_inq_network 1510( 1511 rpc_socket_t desc, 1512 rpc_network_if_id_t *socket_type, 1513 rpc_network_protocol_id_t *protocol_id, 1514 unsigned32 *status 1515) 1516{ 1517 rpc_socket_error_t serr; 1518 rpc_np_addr_t addr; 1519 boolean is_np; 1520 1521 CODING_ERROR (status); 1522 1523 /* 1524 * Get the socket type. 1525 */ 1526 *protocol_id = 0; 1527 1528 serr = rpc__socket_get_if_id (desc, socket_type); 1529 if (RPC_SOCKET_IS_ERR (serr)) 1530 { 1531 RPC_DBG_GPRINTF (("(desc_inq_network) rpc__socket_get_if_id serr->%d\n",serr)); 1532 *status = rpc_s_cant_get_if_id; 1533 return; 1534 } 1535 1536 addr.len = sizeof(addr) - offsetof(rpc_np_addr_t, sa); 1537 serr = rpc__socket_inq_endpoint (desc, (rpc_addr_p_t)&addr); 1538 if (RPC_SOCKET_IS_ERR (serr)) 1539 { 1540 RPC_DBG_GPRINTF (("(desc_inq_network) rpc__socket_inq_endpoint serr->%d\n", serr)); 1541 *status = rpc_s_cant_get_if_id; 1542 return; 1543 } 1544 1545 if (addr.sa.sun_family != RPC_C_NAF_ID_UXD) 1546 { 1547 RPC_DBG_GPRINTF (("(desc_inq_network) not RPC_C_NAF_ID_UXD socket\n")); 1548 *status = rpc_s_cant_get_if_id; 1549 return; 1550 } 1551 1552 is_np = (strncmp(addr.sa.sun_path, RPC_C_NP_DIR, RPC_C_NP_DIR_LEN) == 0); 1553 1554 /* 1555 * This is a disgusting hack due to the tight binding between 1556 * the BSD socket API and the OSF runtime. Domain sockets use 1557 * the "IP" protocol and named pipes use "ICMP". Yuck. 1558 */ 1559 1560 switch ((int)(*socket_type)) 1561 { 1562 case SOCK_STREAM: *protocol_id = is_np ? RPC_C_NETWORK_PROTOCOL_ID_NP : 1563 RPC_C_NETWORK_PROTOCOL_ID_UXD; 1564 break; 1565 1566 default: 1567 /* 1568 * rpc_m_unk_sock_type 1569 * "(%s) Unknown socket type" 1570 */ 1571 rpc_dce_svc_printf ( 1572 __FILE__, __LINE__, 1573 "%s", 1574 rpc_svc_general, 1575 svc_c_sev_fatal | svc_c_action_abort, 1576 rpc_m_unk_sock_type, 1577 "desc_inq_network" ); 1578 break; 1579 } 1580 1581 *status = rpc_s_ok; 1582} 1583 1584 1585/* 1586**++ 1587** 1588** ROUTINE NAME: set_pkt_nodelay 1589** 1590** SCOPE: INTERNAL - declared locally 1591** 1592** DESCRIPTION: 1593** 1594** INPUTS: 1595** 1596** desc The network descriptor to apply the nodelay 1597** option to. 1598** 1599** INPUTS/OUTPUTS: none 1600** 1601** OUTPUTS: 1602** 1603** status A value indicating the status of the routine. 1604** 1605** IMPLICIT INPUTS: none 1606** 1607** IMPLICIT OUTPUTS: none 1608** 1609** FUNCTION VALUE: none 1610** 1611** SIDE EFFECTS: none 1612** 1613**-- 1614**/ 1615 1616INTERNAL void set_pkt_nodelay 1617( 1618 rpc_socket_t desc, 1619 unsigned32 *status 1620) 1621{ 1622 desc = 0; 1623 *status = rpc_s_ok; 1624} 1625 1626 1627/* 1628**++ 1629** 1630** ROUTINE NAME: is_connect_closed 1631** 1632** SCOPE: INTERNAL - declared locally 1633** 1634** DESCRIPTION: 1635** 1636** This routine is called when a recv on a sequenced packet 1637** socket has returned zero bytes. Since TCP does not support 1638** sequenced sockets the routine is a no-op. "true" is returned 1639** because zero bytes received on a stream socket does mean the 1640** connection is closed. 1641** 1642** INPUTS: 1643** 1644** desc The network descriptor representing the connection. 1645** 1646** INPUTS/OUTPUTS: none 1647** 1648** OUTPUTS: 1649** 1650** status A value indicating the status of the routine. 1651** 1652** IMPLICIT INPUTS: none 1653** 1654** IMPLICIT OUTPUTS: none 1655** 1656** FUNCTION VALUE: 1657** 1658** boolean true if the connection is closed, false otherwise. 1659** 1660** SIDE EFFECTS: none 1661** 1662**-- 1663**/ 1664 1665INTERNAL boolean is_connect_closed 1666( 1667 rpc_socket_t desc ATTRIBUTE_UNUSED, 1668 unsigned32 *status 1669) 1670{ 1671 *status = rpc_s_ok; 1672 return (true); 1673} 1674 1675 1676/* 1677**++ 1678** 1679** ROUTINE NAME: tower_flrs_from_addr 1680** 1681** SCOPE: INTERNAL - declared locally 1682** 1683** DESCRIPTION: 1684** 1685** Creates the lower tower floors from an RPC addr. 1686** 1687** INPUTS: 1688** 1689** rpc_addr RPC addr to convert to lower tower floors. 1690** 1691** INPUTS/OUTPUTS: none 1692** 1693** OUTPUTS: 1694** 1695** lower_flrs The returned lower tower floors. 1696** 1697** status A value indicating the return status of the routine. 1698** 1699** IMPLICIT INPUTS: none 1700** 1701** IMPLICIT OUTPUTS: none 1702** 1703** FUNCTION VALUE: void 1704** 1705** SIDE EFFECTS: none 1706** 1707**-- 1708**/ 1709 1710INTERNAL void tower_flrs_from_addr 1711( 1712 rpc_addr_p_t rpc_addr, 1713 twr_p_t *lower_flrs, 1714 unsigned32 *status 1715) 1716{ 1717 //unsigned32 net_prot_id; 1718 1719 CODING_ERROR (status); 1720 1721#ifdef RPC_NO_TOWER_SUPPORT 1722 1723 *status = rpc_s_coding_error; 1724 1725#else 1726 1727#if 0 1728 /* 1729 * The use of a temporary lower floors twr_t is in anticipation 1730 * of the twr_* routines belonging to a separate library with 1731 * their own memory allocation. In that case, twr_* allocates 1732 * memory for returning the lower towers, and we must copy from 1733 * twr_* memory into our (rpc) memory. After the copy, we free 1734 * the twr_* allocated memory. 1735 * 1736 * For now, twr_* routines also use RPC_MEM_ALLOC and RPC_MEM_FREE, 1737 * so we'll skip the extra copy. 1738 */ 1739 twr_p_t temp_lower_flrs; 1740#endif 1741 1742 /* 1743 * Get the network protocol id (aka transport layer protocol) 1744 * for this RPC addr. 1745 */ 1746 //net_prot_id = RPC_PROTSEQ_INQ_NET_PROT_ID(rpc_addr->rpc_protseq_id); 1747 1748 /* 1749 * Convert sockaddr to lower tower floors. 1750 */ 1751 if (rpc_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 1752 twr_np_lower_flrs_from_sa ((sockaddr_t *) &(rpc_addr->sa), 1753#if 0 1754 &temp_lower_flrs, 1755#else 1756 lower_flrs, 1757#endif 1758 status); 1759 else 1760 twr_uxd_lower_flrs_from_sa ((sockaddr_t *) &(rpc_addr->sa), 1761#if 0 1762 &temp_lower_flrs, 1763#else 1764 lower_flrs, 1765#endif 1766 status); 1767 1768 if (*status != twr_s_ok) 1769 { 1770 return; 1771 } 1772 1773#if 0 1774 /* 1775 * Allocate a tower structure to hold the wire (and nameservice) 1776 * representation of the lower tower floors returned from twr_*(). 1777 * 1778 * The size includes the sizof twr_t + length of the tower floors 1779 * returned from twr_np_lower_flrs_from_sa - 1 (for tower_octet_string[0]. 1780 */ 1781 RPC_MEM_ALLOC ( 1782 *lower_flrs, 1783 twr_p_t, 1784 sizeof(twr_t) + temp_lower_flrs->tower_length - 1, 1785 RPC_C_MEM_TOWER, 1786 RPC_C_MEM_WAITOK ); 1787 1788 /* 1789 * Set the tower length to the length of the tower flrs returnd from 1790 * twr_np_lower_flrs_from_sa. 1791 */ 1792 (*lower_flrs)->tower_length = temp_lower_flrs->tower_length; 1793 1794 /* 1795 * Copy the lower tower floors to the tower octet string. 1796 */ 1797 memcpy ((*lower_flrs)->tower_octet_string, 1798 temp_lower_flrs->tower_octet_string, 1799 temp_lower_flrs->tower_length); 1800 1801 /* 1802 * Free the twr_np_lower_flrs_from_sa allocated memory. 1803 */ 1804 RPC_MEM_FREE (temp_lower_flrs, RPC_C_MEM_TOWER); 1805#endif 1806 1807#endif 1808 1809 return; 1810} 1811 1812/* 1813**++ 1814** 1815** ROUTINE NAME: tower_flrs_to_addr 1816** 1817** SCOPE: INTERNAL - declared locally 1818** 1819** DESCRIPTION: 1820** 1821** Creates an RPC addr from a protocol tower. 1822** 1823** INPUTS: 1824** 1825** tower_octet_string 1826** Protocol tower whose floors are used to construct 1827** an RPC addr 1828** 1829** INPUTS/OUTPUTS: none 1830** 1831** OUTPUTS: 1832** 1833** rpc_addr RPC addr constructed from a protocol tower. 1834** 1835** status A value indicating the return status of the routine: 1836** rpc_s_ok 1837** 1838** IMPLICIT INPUTS: none 1839** 1840** IMPLICIT OUTPUTS: none 1841** 1842** FUNCTION VALUE: void 1843** 1844** SIDE EFFECTS: none 1845** 1846**-- 1847**/ 1848 1849INTERNAL void tower_flrs_to_addr 1850( 1851 byte_p_t tower_octet_string, 1852 rpc_addr_p_t *rpc_addr, 1853 unsigned32 *status 1854) 1855{ 1856 sockaddr_t *sa; 1857 unsigned32 sa_len; 1858 1859 CODING_ERROR (status); 1860 1861#ifdef RPC_NO_TOWER_SUPPORT 1862 1863 *status = rpc_s_coding_error; 1864 1865#else 1866 1867 /* 1868 * Convert the lower floors of a tower to a sockaddr. 1869 */ 1870 if (tower_octet_string[0] == 0x05) /* 5 floors for NP, 4 for LPC */ 1871 twr_np_lower_flrs_to_sa ( 1872 tower_octet_string, /* tower octet string (has flr count). */ 1873 &sa, /* returned sockaddr */ 1874 &sa_len, /* returned sockaddr len */ 1875 status); 1876 else 1877 twr_uxd_lower_flrs_to_sa ( 1878 tower_octet_string, /* tower octet string (has flr count). */ 1879 &sa, /* returned sockaddr */ 1880 &sa_len, /* returned sockaddr len */ 1881 status); 1882 1883 if (*status != rpc_s_ok) 1884 return; 1885 1886 /* 1887 * Call the common NAF routine to create an RPC addr from a sockaddr. 1888 * (rpc__naf_addr_from_sa doesn't dispatch to a naf-specific routine.) 1889 */ 1890 rpc__naf_addr_from_sa (sa, sa_len, rpc_addr, status); 1891 1892 /* 1893 * Always free the twr_np_lower_flrs_to_sa allocated memory - regardless 1894 * of the status from rpc__naf_addr_from_sa. 1895 */ 1896 RPC_MEM_FREE (sa, RPC_C_MEM_SOCKADDR); 1897 1898#endif /* RPC_NO_TOWER_SUPPORT */ 1899 1900 /* 1901 * Return whatever status we had. 1902 */ 1903 return; 1904} 1905 1906 1907/* 1908**++ 1909** 1910** ROUTINE NAME: desc_inq_peer_addr 1911** 1912** SCOPE: INTERNAL - declared locally 1913** 1914** DESCRIPTION: 1915** 1916** Receive a socket descriptor which is queried to obtain family, 1917** remote endpoint and remote network address. If this information appears valid 1918** for an DECnet IV address, space is allocated for an RPC address which 1919** is initialized with the information obtained from this socket. The 1920** address indicating the created RPC address is returned in, arg., rpc_addr. 1921** 1922** INPUTS: 1923** 1924** protseq_id Protocol Sequence ID representing a 1925** particular Network Address Family, 1926** its Transport Protocol, and type. 1927** 1928** desc Descriptor, indicating a socket that 1929** has been created on the local operating 1930** platform. 1931** 1932** INPUTS/OUTPUTS: 1933** 1934** rpc_addr The address of a pointer where the RPC address 1935** created by this routine will be indicated. 1936** 1937** OUTPUTS: 1938** 1939** status A value indicating the status of the routine. 1940** 1941** rpc_s_ok The call was successful. 1942** 1943** rpc_s_no_memory Call to malloc failed to allocate memory. 1944** 1945** rpc_s_cant_get_peername Call to getpeername failed. 1946** 1947** rpc_s_invalid_naf_id Socket that arg desc refers is not DECnet IV. 1948** 1949** Any of the RPC Protocol Service status codes. 1950** 1951** IMPLICIT INPUTS: none 1952** 1953** IMPLICIT OUTPUTS: none 1954** 1955** FUNCTION VALUE: none 1956** 1957** SIDE EFFECTS: none 1958** 1959**-- 1960**/ 1961 1962INTERNAL void desc_inq_peer_addr 1963( 1964 rpc_protseq_id_t protseq_id, 1965 rpc_socket_t desc, 1966 rpc_addr_p_t *rpc_addr, 1967 unsigned32 *status 1968) 1969{ 1970 rpc_socket_error_t serr; 1971 rpc_np_addr_p_t np_addr; 1972 rpc_np_addr_t loc_np_addr; 1973 1974 CODING_ERROR (status); 1975 1976 /* 1977 * allocate memory for the new RPC address 1978 */ 1979 RPC_MEM_ALLOC (np_addr, 1980 rpc_np_addr_p_t, 1981 sizeof (rpc_np_addr_t), 1982 RPC_C_MEM_RPC_ADDR, 1983 RPC_C_MEM_WAITOK); 1984 1985 /* 1986 * successful malloc 1987 */ 1988 if (np_addr == NULL) 1989 { 1990 *status = rpc_s_no_memory; 1991 return; 1992 } 1993 *rpc_addr = (rpc_addr_p_t) np_addr; 1994 1995 /* 1996 * insert individual parameters into RPC address 1997 */ 1998 np_addr->rpc_protseq_id = protseq_id; 1999 np_addr->len = sizeof (struct sockaddr_un); 2000 2001 /* 2002 * Get the peer address (name). 2003 * 2004 * If we encounter an error, free the address structure and return 2005 * the status from the getpeername() call, not the free() call. 2006 */ 2007 2008 memset(np_addr->sa.sun_path, 0, sizeof(np_addr->sa.sun_path)); 2009 2010 if (np_addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_np) 2011 { 2012 memset (&loc_np_addr, 0, sizeof(rpc_np_addr_t)); 2013 loc_np_addr.len = sizeof(loc_np_addr) - offsetof(rpc_np_addr_t, sa); 2014 2015 serr = rpc__socket_inq_endpoint(desc, (rpc_addr_p_t) &loc_np_addr); 2016 if (RPC_SOCKET_IS_ERR (serr)) 2017 { 2018 RPC_DBG_GPRINTF (("(desc_inq_peer_addr) rpc__socket_inq_endpoint serr->%d\n", serr)); 2019 RPC_MEM_FREE (np_addr, RPC_C_MEM_RPC_ADDR); 2020 *status = rpc_s_cant_get_if_id; 2021 return; 2022 } 2023 2024 np_addr->sa = loc_np_addr.sa; 2025 np_addr->sa.sun_family = RPC_C_NAF_ID_UXD; 2026 2027 /* 2028 * Assume that named pipes are unix domain sockets where the 2029 * socket name is the same as the endpoint name. Trim the 2030 * leading path components and prefix "\\PIPE\\" to make it 2031 * into a named pipe endpoint. 2032 */ 2033 struct sockaddr_un tmp = np_addr->sa; 2034 const char *last; 2035 2036 last = strrchr(tmp.sun_path, '/'); 2037 if (!last) { 2038 RPC_MEM_FREE (np_addr, RPC_C_MEM_RPC_ADDR); 2039 *status = rpc_s_no_addrs; 2040 return; 2041 } 2042 2043 snprintf(np_addr->sa.sun_path, sizeof(np_addr->sa.sun_path), 2044 "\\PIPE\\%s", last + 1); 2045 2046 RPC_DBG_GPRINTF(("(desc_inq_peer_addr) peer address is %s (socket->%p)\n", np_addr->sa.sun_path, desc)); 2047 2048 /* currently no way to fill in np_addr->remote_host due to <7664297> */ 2049 2050 *status = rpc_s_ok; 2051 } 2052 else 2053 { 2054 serr = rpc__socket_getpeername (desc, (rpc_addr_p_t)np_addr); 2055 if (RPC_SOCKET_IS_ERR (serr)) 2056 { 2057 RPC_DBG_GPRINTF(("(desc_inq_peer_addr) rpc__socket_getpeername returned %d (socket->%p)\n", serr, desc)); 2058 RPC_MEM_FREE (np_addr, RPC_C_MEM_RPC_ADDR); 2059 *rpc_addr = (rpc_addr_p_t)NULL; 2060 *status = rpc_s_cant_getpeername; 2061 } 2062 else 2063 { 2064 /* Force the address family to a correct value since getpeername can fail 2065 silently on some platforms for UNIX domain sockets */ 2066 np_addr->sa.sun_family = RPC_C_NAF_ID_UXD; 2067 RPC_DBG_GPRINTF(("(desc_inq_peer_addr) peer address is %s (socket->%p)\n", np_addr->sa.sun_path, desc)); 2068 *status = rpc_s_ok; 2069 } 2070 } 2071} 2072 2073 2074/* 2075**++ 2076** 2077** ROUTINE NAME: set_port_restriction 2078** 2079** SCOPE: INTERNAL 2080** 2081** DESCRIPTION: 2082** 2083** Builds an rpc_port_restriction_list_t and glues it into the 2084** rpc_protseq_id_elt_t in the rpc_g_protseq_id[] list. 2085** 2086** INPUTS: 2087** 2088** protseq_id 2089** The protocol sequence id to set port restriction 2090** on. 2091** n_elements 2092** The number of port ranges passed in. 2093** 2094** first_port_name_list 2095** An array of pointers to strings containing the 2096** lower bound port names. 2097** 2098** last_port_name_list 2099** An array of pointers to strings containing the 2100** upper bound port names. 2101** 2102** INPUTS/OUTPUTS: none 2103** 2104** OUTPUTS: 2105** 2106** status 2107** 2108** IMPLICIT INPUTS: none 2109** 2110** IMPLICIT OUTPUTS: none 2111** 2112** FUNCTION VALUE: void 2113** 2114** SIDE EFFECTS: none 2115** 2116**-- 2117**/ 2118 2119INTERNAL void set_port_restriction 2120( 2121 rpc_protseq_id_t protseq_id ATTRIBUTE_UNUSED, 2122 unsigned32 n_elements ATTRIBUTE_UNUSED, 2123 unsigned_char_p_t *first_port_name_list, 2124 unsigned_char_p_t *last_port_name_list, 2125 unsigned32 *status 2126) 2127{ 2128 CODING_ERROR (status); 2129 2130 first_port_name_list = NULL; 2131 last_port_name_list = NULL; 2132 2133 *status = rpc_s_invalid_arg; 2134} /* set_port_restriction */ 2135 2136 2137/* 2138**++ 2139** 2140** ROUTINE NAME: get_next_restricted_port 2141** 2142** SCOPE: INTERNAL 2143** 2144** DESCRIPTION: 2145** 2146** Returns the next restricted port in a sequence. There is no guarantee 2147** that the port is available, that is up to bind() to determine. 2148** 2149** INPUTS: 2150** 2151** protseq_id 2152** The protocol sequence id to get the port on. 2153** 2154** INPUTS/OUTPUTS: none 2155** 2156** OUTPUTS: 2157** 2158** port_name 2159** An IP port name as a text string. 2160** status 2161** 2162** IMPLICIT INPUTS: none 2163** 2164** IMPLICIT OUTPUTS: none 2165** 2166** FUNCTION VALUE: void 2167** 2168** SIDE EFFECTS: none 2169** 2170**-- 2171**/ 2172 2173INTERNAL void get_next_restricted_port 2174( 2175 rpc_protseq_id_t protseq_id ATTRIBUTE_UNUSED, 2176 unsigned_char_p_t *port_name, 2177 unsigned32 *status 2178) 2179{ 2180 CODING_ERROR (status); 2181 2182 port_name = NULL; 2183 2184 /* 2185 * Return an error to tell the caller that there is no range 2186 * restriction on this protocol sequence. 2187 */ 2188 2189 *status = rpc_s_invalid_arg; 2190 return; 2191} /* get_next_restricted_port */ 2192 2193/* 2194**++ 2195** 2196** ROUTINE NAME: inq_max_frag_size 2197** 2198** SCOPE: INTERNAL - declared locally 2199** 2200** DESCRIPTION: 2201** 2202** INPUTS: 2203** 2204** naf_id Network Address Family ID serves 2205** as index into EPV for IP routines. 2206** 2207** iftype Network interface type ID 2208** 2209** protocol Network protocol ID 2210** 2211** INPUTS/OUTPUTS: none 2212** 2213** OUTPUTS: 2214** 2215** max_tpdu 2216** 2217** status A value indicating the status of the routine. 2218** 2219** IMPLICIT INPUTS: none 2220** 2221** IMPLICIT OUTPUTS: none 2222** 2223** FUNCTION VALUE: none 2224** 2225** SIDE EFFECTS: none 2226** 2227**-- 2228**/ 2229 2230INTERNAL void inq_max_frag_size 2231( 2232 rpc_addr_p_t rpc_addr, 2233 unsigned32 *max_frag_size, 2234 unsigned32 *status 2235) 2236{ 2237 rpc_addr = 0; 2238 2239 *status = rpc_s_ok; 2240 2241 *max_frag_size = RPC_C_NP_MAX_LOCAL_FRAG_SIZE; 2242 return; 2243 2244} 2245