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