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**      COMTWRFLR.C
82**
83**  FACILITY:
84**
85**     Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**     Contains the routines necessary to create the individual tower
90**     floors that formulate a protocol tower that is stored in the namespace.
91**
92**
93*/
94
95/*
96 * Include files
97 */
98#include <commonp.h>    /* Private defs for Common component            */
99#include <com.h>        /* Private COM defs for other RPC components    */
100#include <comp.h>       /* Privates for COM Services component          */
101#include <comtwrflr.h>  /* Private defs for this module                 */
102
103
104/*
105**++
106**  ROUTINE NAME:           rpc__tower_flr_free
107**
108**  SCOPE:                  PRIVATE - declared in comtwrflr.h
109**
110**  DESCRIPTION:
111**
112**  Frees the tower floor.
113**
114**  INPUTS:                 none
115**
116**  INPUT/OUTPUTS:
117**
118**      floor               The tower floor to be freed.
119**                          Nulled on output.
120**  OUTPUTS:
121**
122**      status              Returns the status code from the floor free
123**                          operation.  This status code is a value
124**                          that inidicates whether the routine completed
125**                          successfully and, if not,
126**                          why.  Returns:
127**                              rpc_s_ok
128**
129**  IMPLICIT INPUTS:        none
130**
131**  IMPLICIT OUTPUTS:       none
132**
133**  FUNCTION VALUE:         void
134**
135**  SIDE EFFECTS:           none
136**
137**--
138*/
139
140PRIVATE void rpc__tower_flr_free
141(
142    rpc_tower_floor_p_t     *floor,
143    unsigned32              *status
144)
145{
146    CODING_ERROR (status);
147
148    /*
149     * Free the tower floor, freeing the octet string associated
150     * with the each floor only if the free flag is set.
151     */
152    if ((*floor)->free_twr_octet_flag)
153    {
154        RPC_MEM_FREE ((*floor)->octet_string,
155                      RPC_C_MEM_TOWER_FLOOR_OCTET);
156    }
157
158    RPC_MEM_FREE (*floor, RPC_C_MEM_TOWER_FLOOR);
159    *floor = NULL;
160
161    /*
162     * Return the status of the floor free routine.
163     */
164    *status = rpc_s_ok;
165    return;
166}
167
168
169/*
170**++
171**  ROUTINE NAME:           rpc__tower_flr_from_drep
172**
173**  SCOPE:                  PRIVATE - declared in comtwrflr.h
174**
175**  DESCRIPTION:
176**
177**  Creates the RPC-specific tower floor for data representation (floor 2).
178**
179**  INPUTS:
180**
181**      transfer_syntax     Data representation (transfer syntax) to
182**                          convert to a tower floor.
183**
184**  INPUT/OUTPUTS:          none
185**
186**  OUTPUTS:
187**
188**      floor               The returned tower floor.
189**
190**      status              Returns the status code from the data
191**                          representation to floor operation.  This
192**                          status code is a value that inidicates whether
193**                          the routine completed successfully and, if not,
194**                          why.  Returns:
195**                              status of the rpc__tower_flr_from_uuid routine.
196**
197**  IMPLICIT INPUTS:        none
198**
199**  IMPLICIT OUTPUTS:       none
200**
201**  FUNCTION VALUE:         void
202**
203**  SIDE EFFECTS:           none
204**
205**--
206*/
207
208PRIVATE void rpc__tower_flr_from_drep
209(
210    rpc_syntax_id_p_t       transfer_syntax,
211    rpc_tower_floor_p_t     *floor,
212    unsigned32              *status
213)
214{
215    CODING_ERROR (status);
216
217    /*
218     * Get the floor from the tower floor from uuid routine, passing
219     * it the uuid and version number of the transfer syntax.
220     */
221    rpc__tower_flr_from_uuid (&(transfer_syntax->id),
222                              (transfer_syntax->version) & 0x0000FFFF,
223                              (transfer_syntax->version) >> 16,
224                              floor,
225                              status);
226    /*
227     * Return the status of the tower floor from uuid routine.
228     */
229    return;
230}
231
232
233/*
234**++
235**  ROUTINE NAME:           rpc__tower_flr_from_if_id
236**
237**  SCOPE:                  PRIVATE - declared in comtwrflr.h
238**
239**  DESCRIPTION:
240**
241**  Creates the RPC-specific tower floor for the interface id (floor 1).
242**
243**  INPUTS:
244**
245**      if_id               The interface identifier to convert to
246**                          a tower floor.
247**
248**  INPUT/OUTPUTS:          none
249**
250**  OUTPUTS:
251**
252**      floor               The returned tower floor.
253**
254**      status              Returns the status code from the interface id
255**                          to floor operation.  This status code is a
256**                          value that inidicates whether the routine
257**                          completed successfully and, if not, why.
258**                          Returns:
259**                              status of the rpc__tower_flr_from_uuid routine.
260**
261**  IMPLICIT INPUTS:        none
262**
263**  IMPLICIT OUTPUTS:       none
264**
265**  FUNCTION VALUE:         void
266**
267**  SIDE EFFECTS:           none
268**
269**--
270*/
271
272PRIVATE void rpc__tower_flr_from_if_id
273(
274    rpc_if_id_p_t           if_id,
275    rpc_tower_floor_p_t     *floor,
276    unsigned32              *status
277)
278{
279
280    CODING_ERROR (status);
281
282    /*
283     * Get the floor from tower floor from uuid routine, passing
284     * it the uuid and version number of the interface identifier.
285     */
286    rpc__tower_flr_from_uuid (&(if_id->uuid),
287                              if_id->vers_major,
288                              if_id->vers_minor,
289                              floor,
290                              status);
291    /*
292     * Return the status of the tower floor from uuid routine.
293     */
294    return;
295
296}
297
298
299/*
300**++
301**  ROUTINE NAME:           rpc__tower_flr_from_rpc_prot_id
302**
303**  SCOPE:                  PRIVATE - declared in comtwrflr.h
304**
305**  DESCRIPTION:
306**
307**  Creates the RPC-specific tower floor for the RPC Protocol (floor 3).
308**  The returned floor is encoded for storage in DNS Towers.
309**
310**  INPUTS:
311**
312**      rpc_protseq_id      The RPC protocol sequence id from which the
313**                          tower protocol id and version is obtained
314**                          to place in the tower floor.
315**
316**      protocol_version    The RPC protocol version to place in the tower.
317**
318**  INPUT/OUTPUTS:          none
319**
320**  OUTPUTS:
321**
322**      floor               The returned tower floor.
323**
324**      status              Returns the status code from the protocol id
325**                          to floor operation.  This status code is a
326**                          value that indicates whether the routine
327**                          completed successfully and, if not, why.
328**                          Returns:
329**                              rpc_s_ok
330**
331**  IMPLICIT INPUTS:        none
332**
333**  IMPLICIT OUTPUTS:       none
334**
335**  FUNCTION VALUE:         void
336**
337**  SIDE EFFECTS:           none
338**
339**--
340*/
341
342PRIVATE void rpc__tower_flr_from_rpc_prot_id
343(
344    rpc_protseq_id_t        rpc_protseq_id,
345    rpc_protocol_version_p_t protocol_version,
346    rpc_tower_floor_p_t     *floor,
347    unsigned32              *status
348)
349{
350    unsigned8       tower_protocol_id;
351    unsigned16      prot_id_size,
352                    address_size,
353                    tower_vers_minor,
354                    twr_rep_16;
355    unsigned32      floor_size,
356                    version_major,
357                    version_minor;
358
359    CODING_ERROR (status);
360
361    /*
362     * Allocate the tower floor structure.
363     */
364    RPC_MEM_ALLOC (
365        *floor, rpc_tower_floor_p_t, sizeof (rpc_tower_floor_t),
366       RPC_C_MEM_TOWER_FLOOR, RPC_C_MEM_WAITOK);
367
368    /*
369     * Calculate the actual size of the tower floor
370     * and allocate.
371     */
372    prot_id_size = RPC_C_TOWER_PROT_ID_SIZE;
373    address_size = RPC_C_TOWER_VERSION_SIZE;
374    floor_size = RPC_C_TOWER_FLR_LHS_COUNT_SIZE +       /* lhs count */
375                 prot_id_size                   +       /* protocol id */
376                 RPC_C_TOWER_FLR_RHS_COUNT_SIZE +       /* rhs count */
377                 address_size;                          /* minor version */
378
379    RPC_MEM_ALLOC (
380        (*floor)->octet_string, byte_p_t, floor_size,
381        RPC_C_MEM_TOWER_FLOOR_OCTET, RPC_C_MEM_WAITOK);
382
383    /*
384     * Initialize the tower floor fields.
385     */
386    (*floor)->free_twr_octet_flag = true;
387    (*floor)->prot_id_count = prot_id_size;
388    (*floor)->address_count = address_size;
389
390    /*
391     * Initialize the tower floor's octet string.
392     */
393
394    /*
395     * Convert the prot_id_count to little endian
396     * representation and copy to the octet string.
397     */
398    twr_rep_16 = (*floor)->prot_id_count;
399    RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16);
400    memcpy ((char *)RPC_PROT_ID_COUNT (*floor), (char *)&twr_rep_16,
401            RPC_C_TOWER_FLR_LHS_COUNT_SIZE);
402
403    /*
404     * Obtain the RPC tower protocol id and minor version number
405     */
406    rpc__network_inq_prot_version (rpc_protseq_id,  &tower_protocol_id,
407        &version_major, &version_minor, status);
408
409    if (*status != rpc_s_ok)
410    {
411        RPC_MEM_FREE ((*floor)->octet_string, RPC_C_MEM_TOWER_FLOOR_OCTET);
412        RPC_MEM_FREE (*floor, RPC_C_MEM_TOWER_FLOOR);
413        return;
414    }
415
416    /*
417     * Copy the RPC tower protocol id to the octet string.
418     */
419    memcpy ((char *)RPC_PROT_ID_START (*floor),
420            (char *)&tower_protocol_id, (*floor)->prot_id_count);
421
422    /*
423     * Convert the address_count (rhs) to little endian
424     * representation and copy to the octet string.
425     */
426    twr_rep_16 = (*floor)->address_count;
427    RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16);
428    memcpy ((char *)RPC_ADDRESS_COUNT (*floor), (char *)&twr_rep_16,
429            RPC_C_TOWER_FLR_RHS_COUNT_SIZE);
430
431    /*
432     * Copy the RPC protocol minor version to the octet string,
433     * after converting to little endian representation.
434     *
435     * Note, we do not need to store the major version of the
436     * protocol in the tower.  If a major revision is made to the
437     * protocol, the architecture will define a new tower protocol id,
438     * since it is a new protocol in itself.
439     *
440     * If we are provided with a minor version, use it instead of
441     * our hardwired value.
442     */
443    if (protocol_version != NULL)
444    {
445        tower_vers_minor = (unsigned16) protocol_version->minor_version;
446    }
447    else
448    {
449        tower_vers_minor = (unsigned16) version_minor;
450    }
451    RPC_RESOLVE_ENDIAN_INT16 (tower_vers_minor);
452    memcpy ((char *)RPC_ADDRESS_START (*floor), (char *)&tower_vers_minor,
453            (*floor)->address_count);
454
455    *status = rpc_s_ok;
456    return;
457}
458
459
460/*
461**++
462**  ROUTINE NAME:           rpc__tower_flr_from_uuid
463**
464**  SCOPE:                  PRIVATE - declared in comtwrflr.h
465**
466**  DESCRIPTION:
467**
468**  Creates the RPC-specific tower floor for UUIDs (floors 1 and 2).
469**
470**  INPUTS:
471**
472**      uuid                The uuid to place in the protocol
473**                          identifier field of the tower floor.
474**
475**      version_major       The major version number to place in the
476**                          protocol identifier field of the tower floor.
477**
478**      version_minor       The minor version number to place in the
479**                          protocol identifier field of the tower floor.
480**
481**  INPUT/OUTPUTS:          none
482**
483**  OUTPUTS:
484**
485**      floor               The returned tower floor.
486**
487**      status              Returns the status code from the UUID
488**                          to floor operation.  This status code is a
489**                          value that indicates whether the routine
490**                          completed successfully and, if not, why.
491**                          Returns:
492**                              rpc_s_ok
493**
494**  IMPLICIT INPUTS:        none
495**
496**  IMPLICIT OUTPUTS:       none
497**
498**  FUNCTION VALUE:         void
499**
500**  SIDE EFFECTS:           none
501**
502**--
503*/
504
505PRIVATE void rpc__tower_flr_from_uuid
506(
507    uuid_p_t                uuid,
508    unsigned32              version_major,
509    unsigned32              version_minor,
510    rpc_tower_floor_p_t     *floor,
511    unsigned32              *status
512)
513{
514    byte_p_t        prot_id;
515    unsigned16      address_size,
516                    tower_vers_minor,
517                    twr_rep_16;
518    unsigned32      floor_size,
519                    prot_id_len;
520
521    CODING_ERROR (status);
522
523    /*
524     * Encode the uuid and major version number into the
525     * protocol identifier (lhs) for storage in the tower floor.
526     */
527    rpc__tower_flr_id_from_uuid
528        (uuid, version_major, &prot_id_len, &prot_id, status);
529
530    if (*status != rpc_s_ok)
531    {
532        return;
533    }
534
535    /*
536     * Allocate the tower floor structure.
537     */
538    RPC_MEM_ALLOC (
539        *floor, rpc_tower_floor_p_t, sizeof (rpc_tower_floor_t),
540       RPC_C_MEM_TOWER_FLOOR, RPC_C_MEM_WAITOK);
541
542    /*
543     * Calculate the actual size of the tower floor
544     * and allocate.
545     */
546    address_size = RPC_C_TOWER_VERSION_SIZE;
547    floor_size = RPC_C_TOWER_FLR_LHS_COUNT_SIZE +       /* lhs count */
548                 prot_id_len                    +       /* protocol id */
549                 RPC_C_TOWER_FLR_RHS_COUNT_SIZE +       /* rhs count */
550                 address_size;                          /* minor version */
551
552    RPC_MEM_ALLOC (
553        (*floor)->octet_string, byte_p_t, floor_size,
554        RPC_C_MEM_TOWER_FLOOR_OCTET, RPC_C_MEM_WAITOK);
555
556    /*
557     * Initialize the tower floor fields.
558     */
559    (*floor)->free_twr_octet_flag = true;
560    (*floor)->prot_id_count = (unsigned16) prot_id_len;
561    (*floor)->address_count = address_size;
562
563    /*
564     * Initialize the tower floor's octet string.
565     */
566
567    /*
568     * Convert the prot_id count to to little endian
569     * representationt and copy to the octet string.
570     */
571    twr_rep_16 = (*floor)->prot_id_count;
572    RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16);
573    memcpy ((char *) RPC_PROT_ID_COUNT (*floor),
574            (char *) &twr_rep_16,
575            RPC_C_TOWER_FLR_LHS_COUNT_SIZE);
576
577    /*
578     * Copy the encoded protocol identifier to the octet string.
579     * It's already in little endian frm rpc__tower_flr_id_from_uuid.
580     */
581    memcpy ((char *)RPC_PROT_ID_START (*floor), (char *)prot_id,
582            prot_id_len);
583
584    /*
585     * Free the protocol identifier now that we are done with it.
586     */
587    RPC_MEM_FREE (prot_id, RPC_C_MEM_TOWER_FLOOR_ID);
588
589    /*
590     * Convert the address count to little endian
591     * representation and copy to the octet string.
592     */
593    twr_rep_16 = (*floor)->address_count;
594    RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16);
595    memcpy ((char *)RPC_ADDRESS_COUNT (*floor), (char *)&twr_rep_16,
596            RPC_C_TOWER_FLR_RHS_COUNT_SIZE);
597
598    /*
599     * Copy the RPC protocol minor version to the octet string,
600     * after converting to little endian representation.
601     */
602    tower_vers_minor = (unsigned16) version_minor;
603    RPC_RESOLVE_ENDIAN_INT16 (tower_vers_minor);
604    memcpy ((char *)RPC_ADDRESS_START (*floor), (char *)&tower_vers_minor,
605            (*floor)->address_count);
606
607    *status = rpc_s_ok;
608    return;
609}
610
611
612/*
613**++
614**  ROUTINE NAME:       rpc__tower_flr_id_from_uuid
615**
616**  SCOPE:              PRIVATE - declared in comtwrflr.h
617**
618**  DESCRIPTION:
619**
620**  Creates a tower floor protocol identifier from a UUID
621**  and major version for storage in a tower floor.
622**
623**  INPUTS:
624**
625**      uuid            Pointer to the UUID to encode into the
626**                      tower floor protocol identifier.
627**
628**      version_major   Major version number to encode into the
629**                      tower floor protocol identifier.
630**
631**  INPUT/OUTPUTS:      none
632**
633**  OUTPUTS:
634**
635**      prot_id_len     Returns the length of the tower floor protocol id.
636**
637**      prot_id         Returns the tower floor protocol identifier.
638**
639**      status          Returns the status code from the protocol id
640**                      from uuid operation.  This status code is a
641**                      value that indicates whether the routine
642**                      completed successfully and, if not, why.
643**                      Returns:
644**                          rpc_s_ok
645**
646**  IMPLICIT INPUTS:    none
647**
648**  IMPLICIT OUTPUTS:   none
649**
650**  FUNCTION VALUE:     void
651**
652**  SIDE EFFECTS:       none
653**
654**--
655*/
656
657PRIVATE void rpc__tower_flr_id_from_uuid
658(
659    uuid_p_t        uuid,
660    unsigned32      version_major,
661    unsigned32      *prot_id_len,
662    byte_p_t        *prot_id,
663    unsigned32      *status
664)
665{
666
667    byte_t          prot_id_prefix = RPC_C_PROT_ID_PREFIX,
668                    *prot_id_p;
669    unsigned16      tower_vers_major;
670    idl_uuid_t          tower_uuid;
671
672    CODING_ERROR (status);
673
674    /*
675     * Calculate the length of the returned tower floor
676     * protocol id.
677     */
678    *prot_id_len =
679        RPC_C_TOWER_PROT_ID_SIZE +        /* protocol id prefix (0x0D) */
680        RPC_C_TOWER_UUID_SIZE +           /* UUID of interest          */
681        RPC_C_TOWER_VERSION_SIZE;         /* major version number      */
682
683    /*
684     * Allocate the protocol identifier.
685     */
686    RPC_MEM_ALLOC (
687        *prot_id, byte_p_t, *prot_id_len,
688        RPC_C_MEM_TOWER_FLOOR_ID, RPC_C_MEM_WAITOK);
689
690    prot_id_p = *prot_id;
691
692    /*
693     * Copy the RPC protocol id prefix.
694     * One byte, no need to convert.
695     */
696    memcpy ((char *)prot_id_p, (char *)&prot_id_prefix,
697        RPC_C_TOWER_PROT_ID_SIZE);
698    prot_id_p++;
699
700    /*
701     * Convert the UUID of interest to little endian and copy it.
702     */
703    tower_uuid = *uuid;
704    RPC_RESOLVE_ENDIAN_UUID (tower_uuid);
705
706    memcpy ((char *)prot_id_p, (char *)&tower_uuid, RPC_C_TOWER_UUID_SIZE);
707    prot_id_p += RPC_C_TOWER_UUID_SIZE;
708
709    /*
710     * Copy the major version and convert to little endian.
711     */
712    tower_vers_major = (unsigned16) version_major;
713    RPC_RESOLVE_ENDIAN_INT16 (tower_vers_major);
714    memcpy ((char *)prot_id_p, (char *)&tower_vers_major,
715        RPC_C_TOWER_VERSION_SIZE);
716
717    *status = rpc_s_ok;
718    return;
719}
720
721
722/*
723**++
724**  ROUTINE NAME:       rpc__tower_flr_id_to_uuid
725**
726**  SCOPE:              PRIVATE - declared in comtwrflr.h
727**
728**  DESCRIPTION:
729**
730**  Converts a tower floor protocol identifier to a UUID
731**  and major version number.
732**
733**  INPUTS:
734**
735**      prot_id         Protocol identifier to decode into a UUID
736**                      a major version number.
737**
738**  INPUT/OUTPUTS:      none
739**
740**  OUTPUTS:
741**
742**      uuid            Returned UUID.
743**
744**      version_major   Returned major version number.
745**
746**      status          Returns the status code from the protocol id
747**                      to uuid operation.  This status code is a
748**                      value that indicates whether the routine
749**                      completed successfully and, if not, why.
750**                      Returns:
751**                          rpc_s_ok
752**
753**  IMPLICIT INPUTS:    none
754**
755**  IMPLICIT OUTPUTS:   none
756**
757**  FUNCTION VALUE:     void
758**
759**  SIDE EFFECTS:       none
760**
761**--
762*/
763
764PRIVATE void rpc__tower_flr_id_to_uuid
765(
766    byte_p_t        prot_id,
767    idl_uuid_t          *uuid,
768    unsigned32      *version_major,
769    unsigned32      *status
770)
771{
772    byte_t          prot_id_prefix,
773                    *prot_id_p;
774    unsigned16      flr_vers_major;
775
776    CODING_ERROR (status);
777
778    /*
779     * Copy the pointer to the protocol identifier.
780     */
781    prot_id_p = prot_id;
782
783    /*
784     * Copy the protocol id prefix and compare with the expected value.
785     * One byte, no conversion necessary.
786     */
787    memcpy ((char *)&prot_id_prefix, (char *)prot_id_p,
788        RPC_C_TOWER_PROT_ID_SIZE);
789
790    if (prot_id_prefix != RPC_C_PROT_ID_PREFIX)
791    {
792        *status = rpc_s_invalid_rpc_floor;
793    }
794
795    prot_id_p++;
796
797    /*
798     * Copy the uuid and resolve to host's endian.
799     */
800    memcpy ((char *)uuid, (char *)prot_id_p, RPC_C_TOWER_UUID_SIZE);
801    RPC_RESOLVE_ENDIAN_UUID (*uuid);
802
803    prot_id_p += RPC_C_TOWER_UUID_SIZE;
804
805    /*
806     * Copy the major version and resolve to host's endian.
807     */
808    memcpy ((char *)&flr_vers_major, (char *)prot_id_p,
809        RPC_C_TOWER_VERSION_SIZE);
810    RPC_RESOLVE_ENDIAN_INT16 (flr_vers_major);
811
812    *version_major = (unsigned32) flr_vers_major;
813
814    *status = rpc_s_ok;
815    return;
816}
817
818
819/*
820**++
821**  ROUTINE NAME:       rpc__tower_flr_to_drep
822**
823**  SCOPE:              PRIVATE - declared in comtwrflr.h
824**
825**  DESCRIPTION:
826**
827**  Converts a tower floor to a data representation (transfer syntax)
828**  compatible with the caller's host architecture.
829**
830**  INPUTS:
831**
832**      floor           The tower floor to convert to a data representation
833**                      (transfer syntax).
834**
835**  INPUT/OUTPUTS:      none
836**
837**  OUTPUTS:
838**
839**      transfer_syntax The returned transfer syntax.
840**
841**      status          Returns the status code from the floor to data
842**                      representation operation.  This status code is a
843**                      value that indicates whether the routine completed
844**                      successfully and, if not, why.  Returns:
845**                        status of the tower floor to uuid routine.
846**
847**  IMPLICIT INPUTS:    none
848**
849**  IMPLICIT OUTPUTS:   none
850**
851**  FUNCTION VALUE:     void
852**
853**  SIDE EFFECTS:       none
854**
855**--
856*/
857
858PRIVATE void rpc__tower_flr_to_drep
859(
860    rpc_tower_floor_p_t     floor,
861    rpc_syntax_id_t         *transfer_syntax,
862    unsigned32              *status
863)
864{
865    unsigned32      version_major,
866                    version_minor;
867
868    CODING_ERROR (status);
869
870    /*
871     * Convert the floor to a data representation by calling the
872     * floor to uuid operation.
873     */
874    rpc__tower_flr_to_uuid (floor, &(transfer_syntax->id),
875                            &version_major, &version_minor, status);
876
877    /*
878     * Place the two version numbers into a single unsigned32
879     * version for the transfer syntax.
880     */
881     transfer_syntax->version = version_minor << 16;
882     transfer_syntax->version |= version_major;
883
884    /*
885     * Return the status of the tower floor to uuid operation.
886     */
887
888    return;
889}
890
891
892/*
893**++
894**  ROUTINE NAME:       rpc__tower_flr_to_if_id
895**
896**  SCOPE:              PRIVATE - declared in comtwrflr.h
897**
898**  DESCRIPTION:
899**
900**  Converts a tower floor to an interface identifer compatible
901**  with the caller's host architecture.
902**
903**  INPUTS:
904**
905**      floor           The tower floor to convert to an interface id.
906**
907**  INPUT/OUTPUTS:      none
908**
909**  OUTPUTS:
910**
911**      if_id           The returned interface identifier.
912**      status          Returns the status code from the floor to if id
913**                      operation.  This status code is a value that
914**                      indicates whether the routine completed successfully
915**                      and, if not, why.  Returns:
916**                        status from the tower floor to uuid routine.
917**
918**  IMPLICIT INPUTS:    none
919**
920**  IMPLICIT OUTPUTS:   none
921**
922**  FUNCTION VALUE:     void
923**
924**  SIDE EFFECTS:       none
925**
926**--
927*/
928
929PRIVATE void rpc__tower_flr_to_if_id
930(
931    rpc_tower_floor_p_t     floor,
932    rpc_if_id_t             *if_id,
933    unsigned32              *status
934)
935{
936    unsigned32          version_major,
937                        version_minor;
938
939    CODING_ERROR (status);
940
941    /*
942     * Call the tower floor to uuid routine to convert the
943     * this floor to an if-id.
944     */
945    rpc__tower_flr_to_uuid (floor, &(if_id->uuid), &version_major,
946                            &version_minor, status);
947
948    if_id->vers_major = (unsigned16) version_major;
949    if_id->vers_minor = (unsigned16) version_minor;
950
951    /*
952     * Return the status of the tower floor to uuid operation.
953     */
954    return;
955
956}
957
958
959/*
960**++
961**  ROUTINE NAME:       rpc__tower_flr_to_rpc_prot_id
962**
963**  SCOPE:              PRIVATE - declared in comtwrflr.h
964**
965**  DESCRIPTION:
966**
967**  Converts a tower floor to an RPC protocol identifier compatible
968**  with the caller's host architecture.
969**
970**  INPUTS:
971**
972**      floor           The tower floor to convert to a RPC protocol id.
973**
974**  INPUT/OUTPUTS:      none
975**
976**  OUTPUTS:
977**
978**      rpc_protocol_id The returned RPC protocol identifier.
979**
980**      version_major   Returned RPC protocol major version number.
981**
982**      version_minor   Returned RPC protocol minor version number.
983**
984**      status          Returns the status code from the floor to protocol id
985**                      operation.  This status code is a value that
986**                      indicates whether the routine completed successfully
987**                      and, if not, why.  Returns:
988**                        rpc_s_ok
989**                        rpc_s_invalid_rpc_protid
990**
991**  IMPLICIT INPUTS:    none
992**
993**  IMPLICIT OUTPUTS:   none
994**
995**  FUNCTION VALUE:     void
996**
997**  SIDE EFFECTS:       none
998**
999**--
1000*/
1001
1002PRIVATE void rpc__tower_flr_to_rpc_prot_id
1003(
1004    rpc_tower_floor_p_t     floor,
1005    rpc_protocol_id_t       *rpc_protocol_id,
1006    unsigned32              *version_major,
1007    unsigned32              *version_minor,
1008    unsigned32              *status
1009)
1010{
1011    boolean             match;
1012    rpc_protseq_id_t    protseq_id;
1013    unsigned32          i,
1014                        temp_vers_minor;
1015    unsigned16          prot_vers_minor;
1016    unsigned8           network_prot_id;
1017
1018    CODING_ERROR (status);
1019
1020    /*
1021     * For each possible RPC protocol sequence
1022     * find the protocol id that matches the tower's.
1023     */
1024    for (i=0, match = false; i < RPC_C_PROTSEQ_ID_MAX; i++)
1025    {
1026
1027        /*
1028         * Get the RPC protocol id for this RPC
1029         * protocol sequence.
1030         */
1031        protseq_id = RPC_PROTSEQ_INQ_PROTSEQ_ID (i);
1032
1033        /*
1034         * Get the network's 'tower' protocol id for this
1035         * protocol sequence and return its major version.
1036         */
1037        rpc__network_inq_prot_version (protseq_id, &network_prot_id,
1038            version_major, &temp_vers_minor, status);
1039
1040        /*
1041         * Ignore protocol sequences not supported by this host
1042         * and continue with next protocol sequence.
1043         */
1044        if (*status == rpc_s_protseq_not_supported)
1045        {
1046            continue;
1047        }
1048
1049        /*
1050         * Return on any other error.
1051         */
1052        if (*status != rpc_s_ok)
1053        {
1054            return;
1055        }
1056
1057        /*
1058         * Obtain the tower's protocol id and see if it
1059         * matches the network's tower protocol id for this
1060         * protocol sequence.
1061         *
1062         * Note: protocol id is only one byte so no need to
1063         * memcpy or convert to host representation.
1064         */
1065        if ((unsigned8) *(RPC_PROT_ID_START(floor)) ==
1066            (unsigned8) network_prot_id)
1067        {
1068            /*
1069             * Return the protocol identifier.
1070             */
1071            *rpc_protocol_id = RPC_PROTSEQ_INQ_PROT_ID (i);
1072
1073            match = true;
1074            break;
1075        }
1076    }
1077
1078    if (match)
1079    {
1080        /*
1081         * Obtain the protocol id's minor version
1082         * from the tower and convert to the host's
1083         * endian representation.
1084         */
1085        memcpy ((char *)&prot_vers_minor, (char *)RPC_ADDRESS_START (floor),
1086                floor->address_count);
1087        RPC_RESOLVE_ENDIAN_INT16 (prot_vers_minor);
1088
1089        /*
1090         * Return the protocol id's minor version and
1091         * set status to success.
1092         */
1093        *version_minor = (unsigned32) prot_vers_minor;
1094
1095        *status = rpc_s_ok;
1096    }
1097    else
1098    {
1099        /*
1100         * No match found on the tower's protocol id.
1101         */
1102        *status = rpc_s_invalid_rpc_protid;
1103    }
1104
1105    return;
1106}
1107
1108
1109/*
1110**++
1111**  ROUTINE NAME:       rpc__tower_flr_to_uuid
1112**
1113**  SCOPE:              PRIVATE - declared in comtwrflr.h
1114**
1115**  DESCRIPTION:
1116**
1117**  Converts a tower floor to UUID and version numbers.
1118**
1119**  INPUTS:
1120**
1121**      floor           The tower floor to convert to a UUID and
1122**                      version numbers.
1123**
1124**  INPUT/OUTPUTS:      none
1125**
1126**  OUTPUTS:
1127**
1128**      uuid            Returned UUID.
1129**
1130**      version_major   Returned major version number.
1131**
1132**      version_minor   Returned minor version number.
1133**
1134**      status          Returns the status code from the floor to protocol id
1135**                      operation.  This status code is a value that
1136**                      indicates whether the routine completed successfully
1137**                      and, if not, why.  Returns:
1138**                        rpc_s_ok
1139**                        status from a called routine
1140**
1141**  IMPLICIT INPUTS:    none
1142**
1143**  IMPLICIT OUTPUTS:   none
1144**
1145**  FUNCTION VALUE:     void
1146**
1147**  SIDE EFFECTS:       none
1148**
1149**--
1150*/
1151
1152PRIVATE void rpc__tower_flr_to_uuid
1153(
1154    rpc_tower_floor_p_t     floor,
1155    idl_uuid_t                  *uuid,
1156    unsigned32              *version_major,
1157    unsigned32              *version_minor,
1158    unsigned32              *status
1159)
1160{
1161    unsigned16          flr_vers_minor;
1162
1163    CODING_ERROR (status);
1164
1165    /*
1166     * Decode the protocol identifier information into the uuid
1167     * and major version number compatible with the host architecture.
1168     */
1169    rpc__tower_flr_id_to_uuid ((byte_p_t)RPC_PROT_ID_START (floor),
1170        uuid, version_major, status);
1171
1172    if (*status != rpc_s_ok)
1173    {
1174        return;
1175    }
1176
1177    /*
1178     * Obtain the address information (right hand side) from the
1179     * tower floor and convert to host's endian.
1180     */
1181    memcpy ((char *)&flr_vers_minor, (char *)RPC_ADDRESS_START (floor),
1182            floor->address_count);
1183
1184    RPC_RESOLVE_ENDIAN_INT16 (flr_vers_minor);
1185
1186    *version_minor = (unsigned32) flr_vers_minor;
1187
1188    *status = rpc_s_ok;
1189
1190    return;
1191}
1192