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