void rpc_binding_inq_prot_seq( rpc_binding_handle_t binding_handle, unsigned32 *prot_seq, unsigned32 *st ) { rpc_binding_rep_p_t binding_r = (rpc_binding_rep_p_t) binding_handle; CODING_ERROR (st); RPC_VERIFY_INIT (); if (binding_r && binding_r->transport_info) { *prot_seq = (unsigned32)binding_r->transport_info->protseq; } else if (binding_r) { *prot_seq = (unsigned32)binding_r->rpc_addr->rpc_protseq_id; } else { *prot_seq = (unsigned32)RPC_C_INVALID_PROTSEQ_ID; } *st = rpc_s_ok; }
void rpc_binding_inq_access_token_caller( rpc_binding_handle_t binding_handle, rpc_access_token_p_t* token, unsigned32* st ) { rpc_binding_rep_p_t binding_r = (rpc_binding_rep_p_t) binding_handle; int err = 0; CODING_ERROR (st); RPC_VERIFY_INIT (); *token = NULL; if (binding_r) { if (binding_r->auth_info) { rpc_g_authn_protocol_id[binding_r->auth_info->authn_protocol].epv-> inq_access_token(binding_r->auth_info, token, st); if (*st != rpc_s_ok) { goto error; } } if (!*token && binding_r->transport_info) { err = rpc_g_protseq_id[binding_r->transport_info->protseq].socket_vtbl-> transport_inq_access_token( binding_r->transport_info->handle, token); if (err) { *st = rpc_s_binding_has_no_auth; goto error; } } } if (!*token) { *st = rpc_s_binding_has_no_auth; goto error; } else { *st = rpc_s_ok; } error: return; }
PUBLIC void rpc_tower_to_binding ( byte_p_t prot_tower, rpc_binding_handle_t *binding, unsigned32 *status ) { rpc_binding_rep_p_t binding_rep; rpc_protocol_id_t prot_id; rpc_addr_p_t rpc_addr; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null binding in case of error before finishing. */ *binding = NULL; /* * Obtain an RPC address for the tower. */ rpc__naf_tower_flrs_to_addr (prot_tower, &rpc_addr, status); if (*status != rpc_s_ok) { return; } prot_id = RPC_PROTSEQ_INQ_PROT_ID(rpc_addr->rpc_protseq_id); /* * Allocate and initialize a binding rep. */ binding_rep = rpc__binding_alloc (false, &uuid_g_nil_uuid, prot_id, rpc_addr, status); /* * Return binding handle to user. */ *binding = (rpc_binding_handle_t) binding_rep; /* * Return status from rpc__binding_alloc */ return; }
void rpc_binding_inq_transport_info( rpc_binding_handle_t binding_handle, rpc_transport_info_handle_t *info, unsigned32 *st ) { rpc_binding_rep_p_t binding_r = (rpc_binding_rep_p_t) binding_handle; CODING_ERROR (st); RPC_VERIFY_INIT (); if (binding_r && binding_r->transport_info) { *info = binding_r->transport_info->handle; } else { *info = NULL; } *st = rpc_s_ok; }
void rpc_binding_set_transport_info( rpc_binding_handle_t binding_handle, rpc_transport_info_handle_t info_handle, unsigned32 *st ) { rpc_socket_error_t serr = RPC_C_SOCKET_OK; rpc_binding_rep_p_t binding_r = (rpc_binding_rep_p_t) binding_handle; CODING_ERROR (st); RPC_VERIFY_INIT (); serr = rpc__transport_info_create( binding_r->rpc_addr->rpc_protseq_id, info_handle, &binding_r->transport_info); if (serr) { *st = rpc_s_no_memory; goto error; } (*rpc_g_protocol_id[binding_r->protocol_id].binding_epv->binding_changed) (binding_r, st); if (*st) { goto error; } *st = rpc_s_ok; error: return; }
PUBLIC void twr_dnet_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * make sure we have a pointer to some data structure */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, twr_c_tower_flr_count_size); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += twr_c_tower_flr_count_size; /* * Skip over the (application's) upper floors while we look for the * beginning of the dnet-specific lower floors. */ for (count = 0; count < floor_count; count++) { /* * Get the length of this floor's protocol id field (don't * advance the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), twr_c_tower_prot_id_size); /* * See if we support the protocol id. */ if ( (id_size == twr_c_tower_prot_id_size) && (id == TWR_C_FLR_PROT_ID_DNA) ) { /* * Indicate we found the beginning of the dnet floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's TWR_C_FLR_PROT_ID_DNA. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for a DECnet sockaddr */ length = sizeof(struct sockaddr_dn); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as a DECnet family socket */ ((struct sockaddr_dn *)(*sa))->sdn_family = RPC_C_NAF_ID_DNET; /* * Length of end user spec */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * End user spec */ memcpy (&((struct sockaddr_dn *)(*sa))->sdn_objnum, (char *)tower, addr_size); tower += addr_size; /* * Length of host transport */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Transport id * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); tower += id_size; if ((id_size != twr_c_tower_prot_id_size) || (id != TWR_C_FLR_PROT_ID_NSP)) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * Length of sdn_flags */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * this field is probably null */ if (addr_size) { memcpy ( &((struct sockaddr_dn *)(*sa))->sdn_flags, (char *)tower, addr_size); tower += addr_size; } /* * Length of routing id */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Protocol id * Expect one byte, so no need to convert. */ memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); tower += id_size; if ( (id_size != twr_c_tower_prot_id_size) || (id != TWR_C_FLR_PROT_ID_ROUTING) ) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * the length of host address */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; memcpy (&((struct sockaddr_dn *)(*sa))->sdn_add, (char *)tower, addr_size); *status = twr_s_ok; }
PUBLIC void twr_dnet_lower_flrs_from_sa ( sockaddr_p_t sa, twr_p_t *lower_flrs, unsigned32 *status ) { unsigned8 protocol_id[TWR_C_NUM_DNA_LOWER_FLRS]; unsigned16 floor_count, id_size = twr_c_tower_prot_id_size, related_data_size[TWR_C_NUM_DNA_LOWER_FLRS], twr_rep_16; unsigned32 count, twr_t_length, *related_data_ptr[TWR_C_NUM_DNA_LOWER_FLRS]; byte_p_t tmp_tower; CODING_ERROR (status); RPC_VERIFY_INIT (); if (sa->family == RPC_C_NAF_ID_DNET) { protocol_id[0] = TWR_C_FLR_PROT_ID_DNA; protocol_id[1] = TWR_C_FLR_PROT_ID_NSP; protocol_id[2] = TWR_C_FLR_PROT_ID_ROUTING; /* * Since we now know the socket address we're dealing with, * collect the sizes of each field to allocate memory, and * remember the pointers to the fields so we can copy the * data once we have allocated the tower string. */ floor_count = TWR_C_NUM_DNA_LOWER_FLRS; related_data_size[0] = sizeof(((struct sockaddr_dn *)sa)->sdn_objnum) + sizeof(((struct sockaddr_dn *)sa)->sdn_objnamel) + ((struct sockaddr_dn *)sa)->sdn_objnamel; related_data_ptr[0] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_objnum); /* do we need to store flags ??? * related_data_size[1] = * sizeof(((struct sockaddr_dn *)sa)->sdn_flags); */ related_data_size[1] = 0; related_data_ptr[1] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_flags); related_data_size[2] = sizeof(((struct sockaddr_dn *)sa)->sdn_add.a_len) + ((struct sockaddr_dn *)sa)->sdn_add.a_len; related_data_ptr[2] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_add); } else { *status = twr_s_unknown_sa; return; } /* * Allocate memory and copy the data into the proper * locations in each of up to three floors. */ /* * Calculate length of tower floor. */ twr_t_length = twr_c_tower_flr_count_size; /* to store floor count */ for ( count = 0; count < floor_count; count++ ) { twr_t_length += TWR_C_FLR_OVERHEAD; twr_t_length += related_data_size[count]; } /* * Next allocate space for the tower structure */ RPC_MEM_ALLOC ( *lower_flrs, twr_p_t, sizeof (twr_t) + (twr_t_length - 1), RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Copy the length of the tower octet string into the tower structure */ (*lower_flrs)->tower_length = twr_t_length; /* * Copy the floor information into the tower octet string */ /* * Use a temporary for the octet string since we need * to increment the pointer. */ tmp_tower = (*lower_flrs)->tower_octet_string; /* * Copy the number of floors into the tower octet string */ twr_rep_16 = floor_count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, twr_c_tower_flr_count_size); tmp_tower += twr_c_tower_flr_count_size; /* * Convert the protocol identifier size to its proper * representation for use in the following loop. */ RPC_RESOLVE_ENDIAN_INT16 (id_size); for (count = 0; count < floor_count; count++) { /* * Copy the length of the protocol identifier field into * tower octet string. (Converted before the loop.) */ memcpy ((char *)tmp_tower, (char *)&id_size, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Copy the protocol identifier into tower octet string * (1 byte so no need to convert endian representation). */ memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), twr_c_tower_prot_id_size); tmp_tower += twr_c_tower_prot_id_size; /* * Copy the length of the address data field into * tower octet string. */ twr_rep_16 = related_data_size[count]; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_RHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; /* * If there is addressing data, copy the address data field into * tower octet string */ if (related_data_size[count]) { memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], related_data_size[count] ); /* * Set up for the next floor. */ tmp_tower += related_data_size[count]; } } *status = twr_s_ok; }
PUBLIC void twr_np_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; char *p; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * Make sure we have a pointer to some data structure. */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } RPC_DBG_GPRINTF(("(twr_np_lower_flrs_to_sa) called\n")); /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, TWR_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Skip over the (application's) upper floors while we look for the * beginning of the np-specific lower floors. */ for ( count = 0; count < floor_count; count++ ) { /* * Get the length of this floor's protocol id field (don't advance * the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), TWR_C_TOWER_PROT_ID_SIZE); /* * See if we support the protocol id. */ if ( (id_size == TWR_C_TOWER_PROT_ID_SIZE) && (id == TWR_C_FLR_PROT_ID_NP)) { /* * Indicate we found the beginning of the np floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's * TWR_C_FLR_PROT_ID_NP. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for sockaddr */ length = sizeof(struct sockaddr_un); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as an internet family socket */ ((struct sockaddr_un *)(*sa))->sun_family = RPC_C_NAF_ID_UXD; /* * Get the length of pipe name */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the pipe name to the sockaddr */ tower[addr_size - 1] = '\0'; addr_size += RPC_C_NP_DIR_LEN + 1; if ((size_t)addr_size + 1 > sizeof(((struct sockaddr_un *)(*sa))->sun_path)) { *status = rpc_s_no_memory; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } snprintf(((struct sockaddr_un *)(*sa))->sun_path, length, "%s/%s", RPC_C_NP_DIR, tower); for (p = ((struct sockaddr_un *)(*sa))->sun_path; *p != '\0'; p++) { if (*p == '\\') *p = '/'; } *status = twr_s_ok; /* For now, disregard the NetBIOS address. */ }
PUBLIC void twr_np_lower_flrs_from_sa ( sockaddr_p_t sa, twr_p_t *lower_flrs, unsigned32 *status ) { unsigned8 protocol_id[TWR_C_NUM_NP_LOWER_FLRS]; unsigned16 id_size = TWR_C_TOWER_PROT_ID_SIZE, floor_count, related_data_size[TWR_C_NUM_NP_LOWER_FLRS], twr_rep_16; unsigned32 count, twr_t_length; byte_p_t related_data_ptr[TWR_C_NUM_NP_LOWER_FLRS], tmp_tower; char hostname[MAXHOSTNAMELEN], *p; CODING_ERROR (status); RPC_VERIFY_INIT (); RPC_DBG_GPRINTF(("(twr_np_lower_flrs_from_sa) called\n")); if (sa->family == RPC_C_NAF_ID_UXD) { protocol_id[0] = TWR_C_FLR_PROT_ID_NP; protocol_id[1] = TWR_C_FLR_PROT_ID_NB; } else { *status = twr_s_unknown_sa; return; } /* * Since we now know the socket address we're dealing with, * collect the sizes of each field to allocate memory, and * remember the pointers to the fields so we can copy the * data once we have allocated the tower string. */ floor_count = TWR_C_NUM_NP_LOWER_FLRS; /* * related_data[0] contains the pipe name (eg. \PIPE\lsass) */ related_data_ptr[0] = (unsigned char*) ((struct sockaddr_un *)sa)->sun_path; if (strncmp((char*) related_data_ptr[0], (char*) RPC_C_NP_DIR"/", RPC_C_NP_DIR_LEN + 1) == 0) { /* Path is relative, but do not chop off first /. */ related_data_ptr[0] += RPC_C_NP_DIR_LEN; } related_data_size[0] = strlen((char*) related_data_ptr[0]) + 1; /* * related_data[1] contains the NetBIOS name (eg. \\MYSERVER) */ hostname[0] = '\\'; hostname[1] = '\\'; gethostname(&hostname[2], MAXHOSTNAMELEN - 3); hostname[MAXHOSTNAMELEN - 1] = '\0'; for (p = &hostname[2]; *p != '\0'; p++) *p = toupper((int)*p); related_data_size[1] = strlen(hostname) + 1; related_data_ptr[1] = (unsigned char*) hostname; /* * Calculate the length of the tower floors. */ twr_t_length = TWR_C_TOWER_FLR_COUNT_SIZE; /* to store floor count */ for ( count = 0; count < floor_count; count++ ) { twr_t_length += TWR_C_FLR_OVERHEAD; twr_t_length += related_data_size[count]; } /* * Next allocate space for the tower structure */ RPC_MEM_ALLOC ( *lower_flrs, twr_p_t, sizeof (twr_t) + (twr_t_length - 1), RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Copy the length of the tower octet string into the tower structure */ (*lower_flrs)->tower_length = twr_t_length; /* * Copy the floor information into the tower octet string */ /* * Use a temporary for the octet string since we need * to increment the pointer. */ tmp_tower = (*lower_flrs)->tower_octet_string; /* * Copy the number of floors into the tower octet string */ twr_rep_16 = floor_count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Convert the protocol identifier size to its proper * representation for use in the following loop. */ RPC_RESOLVE_ENDIAN_INT16 (id_size); for ( count = 0; count < floor_count; count++ ) { /* * Copy the length of the protocol identifier field into * tower octet string. (Converted before the loop.) */ memcpy ((char *)tmp_tower, (char *)&id_size, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Copy the protocol identifier into tower octet string * (1 byte so no need to convert endian representation). */ memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), TWR_C_TOWER_PROT_ID_SIZE); tmp_tower += TWR_C_TOWER_PROT_ID_SIZE; /* * Copy the length of the address data field into * tower octet string. */ twr_rep_16 = related_data_size[count]; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_RHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; /* * If there is addressing data, copy the address data field into * tower octet string */ if (related_data_size[count]) { memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], related_data_size[count]); /* Convert slashes */ for (p = (char*) tmp_tower; *p != '\0'; p++) { if (*p == '/') *p = '\\'; } /* * Set up for the next floor. */ tmp_tower += related_data_size[count]; } } *status = twr_s_ok; }
PUBLIC void twr_ip_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * Make sure we have a pointer to some data structure. */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, TWR_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Skip over the (application's) upper floors while we look for the * beginning of the ip-specific lower floors. */ for ( count = 0; count < floor_count; count++ ) { /* * Get the length of this floor's protocol id field (don't advance * the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), TWR_C_TOWER_PROT_ID_SIZE); /* * See if we support the protocol id. */ if ( (id_size == TWR_C_TOWER_PROT_ID_SIZE) && (id == TWR_C_FLR_PROT_ID_TCP || id == TWR_C_FLR_PROT_ID_UDP)) { /* * Indicate we found the beginning of the ip floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's * TWR_C_FLR_PROT_ID_TCP or TWR_C_FLR_PROT_ID_UDP. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for ip sockaddr */ length = sizeof(struct sockaddr_in); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as an internet family socket */ ((struct sockaddr_in *)(*sa))->sin_family = RPC_C_NAF_ID_IP; /* * Get the length of in_port */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the port number to the sockaddr. */ memcpy ( &((struct sockaddr_in *)(*sa))->sin_port, tower, addr_size); tower += addr_size; /* * Get the length of host address floor protocol id */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Get the protocol id * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)tower, TWR_C_TOWER_PROT_ID_SIZE); tower += id_size; if ( (id_size != TWR_C_TOWER_PROT_ID_SIZE) || (id != TWR_C_FLR_PROT_ID_IP) ) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * Get the length of in_address */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the host address to the sockaddr */ memcpy (&((struct sockaddr_in *)(*sa))->sin_addr.s_addr, (char *)tower, addr_size); *status = twr_s_ok; }
PUBLIC void twr_ip_lower_flrs_from_sa ( unsigned32 trans_prot, sockaddr_p_t sa, twr_p_t *lower_flrs, unsigned32 *status ) { unsigned8 protocol_id[TWR_C_NUM_IP_LOWER_FLRS]; unsigned16 id_size = TWR_C_TOWER_PROT_ID_SIZE, floor_count, related_data_size[TWR_C_NUM_IP_LOWER_FLRS], twr_rep_16; unsigned32 count, twr_t_length; byte_p_t related_data_ptr[TWR_C_NUM_IP_LOWER_FLRS], tmp_tower; static unsigned8 zeroes[TWR_C_IP_ADDR_SIZE] = {0}; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * all depends on the network family to which this socket belongs */ if (sa->family == RPC_C_NAF_ID_IP || sa->family == RPC_C_NAF_ID_IP6) { /* * only two network protocols are supported for internet */ if (trans_prot == RPC_C_NETWORK_PROTOCOL_ID_TCP) { protocol_id[0] = TWR_C_FLR_PROT_ID_TCP; } else { if ( trans_prot == RPC_C_NETWORK_PROTOCOL_ID_UDP ) { protocol_id[0] = TWR_C_FLR_PROT_ID_UDP; } else { *status = twr_s_unknown_sa; return; } } protocol_id[1] = TWR_C_FLR_PROT_ID_IP; } else { *status = twr_s_unknown_sa; return; } /* * Since we now know the socket address we're dealing with, * collect the sizes of each field to allocate memory, and * remember the pointers to the fields so we can copy the * data once we have allocated the tower string. */ floor_count = TWR_C_NUM_IP_LOWER_FLRS; /* * Note that the port number and address are already * stored in big endian (network order) which is what * the architecture specifies, so no endian conversion * is necessary. */ switch (sa->family) { case RPC_C_NAF_ID_IP: related_data_size[0] = TWR_C_IP_PORT_SIZE; related_data_ptr[0] = (byte_p_t) (&((struct sockaddr_in *)sa)->sin_port); related_data_size[1] = TWR_C_IP_ADDR_SIZE; related_data_ptr[1] = (byte_p_t) (&((struct sockaddr_in *)sa)->sin_addr.s_addr); break; case RPC_C_NAF_ID_IP6: related_data_size[0] = TWR_C_IP_PORT_SIZE; related_data_ptr[0] = (byte_p_t) (&((struct sockaddr_in6 *)sa)->sin6_port); // Use zeroes for address related_data_size[1] = TWR_C_IP_ADDR_SIZE; related_data_ptr[1] = (byte_p_t) zeroes; break; default: abort(); } /* * Calculate the length of the tower floors. */ twr_t_length = TWR_C_TOWER_FLR_COUNT_SIZE; /* to store floor count */ for ( count = 0; count < floor_count; count++ ) { twr_t_length += TWR_C_FLR_OVERHEAD; twr_t_length += related_data_size[count]; } /* * Next allocate space for the tower structure */ RPC_MEM_ALLOC ( *lower_flrs, twr_p_t, sizeof (twr_t) + (twr_t_length - 1), RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Copy the length of the tower octet string into the tower structure */ (*lower_flrs)->tower_length = twr_t_length; /* * Copy the floor information into the tower octet string */ /* * Use a temporary for the octet string since we need * to increment the pointer. */ tmp_tower = (*lower_flrs)->tower_octet_string; /* * Copy the number of floors into the tower octet string */ twr_rep_16 = floor_count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Convert the protocol identifier size to its proper * representation for use in the following loop. */ RPC_RESOLVE_ENDIAN_INT16 (id_size); for ( count = 0; count < floor_count; count++ ) { /* * Copy the length of the protocol identifier field into * tower octet string. (Converted before the loop.) */ memcpy ((char *)tmp_tower, (char *)&id_size, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Copy the protocol identifier into tower octet string * (1 byte so no need to convert endian representation). */ memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), TWR_C_TOWER_PROT_ID_SIZE); tmp_tower += TWR_C_TOWER_PROT_ID_SIZE; /* * Copy the length of the address data field into * tower octet string. */ twr_rep_16 = related_data_size[count]; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_RHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; /* * If there is addressing data, copy the address data field into * tower octet string */ if (related_data_size[count]) { memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], related_data_size[count]); /* * Set up for the next floor. */ tmp_tower += related_data_size[count]; } } *status = twr_s_ok; }
PUBLIC void rpc_tower_vector_from_binding ( rpc_if_handle_t if_spec, rpc_binding_handle_t binding, rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { rpc_tower_ref_vector_t *tower_ref_vector; unsigned int i; unsigned32 temp_status; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null the twr_vector in case of error before finishing. */ *twr_vector = NULL; if (if_spec == NULL) { *status = rpc_s_no_interfaces; return; } /* * Convert the binding to a vector of tower refs. */ rpc__tower_ref_vec_from_binding ((rpc_if_rep_p_t)if_spec, binding, &tower_ref_vector, status); if (*status != rpc_s_ok) { /* * No need to goto CLEANUP; since a tower_ref_vector wasn't * returned to us. */ return; } /* * Allocate a rpc_tower_vector_t based on the number of returned * tower refs. */ RPC_MEM_ALLOC ( *twr_vector, rpc_tower_vector_p_t, sizeof (rpc_tower_vector_t) + (tower_ref_vector->count - 1) * sizeof (twr_p_t), RPC_C_MEM_TOWER_VECTOR, RPC_C_MEM_WAITOK ); (*twr_vector)->count = tower_ref_vector->count; /* * For each returned tower ref convert the tower ref to a twr_t and * store the twr_t in the rpc_tower_vector_t. */ for (i = 0; i < tower_ref_vector->count; i++) { rpc__tower_from_tower_ref (tower_ref_vector->tower[i], &(*twr_vector)->tower[i], status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); goto CLEANUP; } } CLEANUP: /* * Free the tower_ref_vector returned from * rpc__tower_ref_vec_from_binding(). */ rpc__tower_ref_vec_free (&tower_ref_vector, &temp_status); /* * If we got this far successfully, return whatever the result from * rpc__tower_ref_vec_free(). Otherwise, return the previous error * in status. */ if (*status == rpc_s_ok) { *status = temp_status; } return; }