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** twr_dnet.c 82** 83** FACILITY: 84** 85** Protocol Tower Services for the DECnet address family 86** 87** ABSTRACT: 88** 89** The protocol tower service provides routines that: 90** 91** o convert a socket address to the lower floors of 92** a protocol tower 93** 94** o convert a protocol tower to a socket address 95** 96** 97*/ 98 99#include <commonp.h> /* Common declarations for all RPC runtime */ 100#if NAF_DNET 101#include <com.h> /* Common communications services */ 102#include <twrp.h> /* Private tower services */ 103 104/* 105 * Include the DECnet specific socket address 106 */ 107#ifdef unix 108#include <netdnet/dn.h> 109#else 110#include <dn.h> 111#endif 112 113/* 114**++ 115** 116** ROUTINE NAME: twr_dnet_lower_flrs_from_sa 117** 118** SCOPE: PUBLIC - declared in twr.idl 119** 120** DESCRIPTION: 121** 122** Creates the canonical representation of a DECnet protocol tower's 123** lower floors from a sockadddr. The canonical form can be transmitted 124** on the wire, or included in a DNA tower. 125** 126** INPUTS: 127** 128** sa DECnet-specific socket address data structure. 129** 130** INPUTS/OUTPUTS: none 131** 132** OUTPUTS: 133** 134** lower_flrs Returns the lower tower floors in a twr_t 135** structure (includes the floor count as the first 136** field of "tower_octet_string" member). 137** 138** status A value indicating the return status of the routine: 139** twr_s_ok 140** twr_s_unknown_sa 141** 142** IMPLICIT INPUTS: none 143** 144** IMPLICIT OUTPUTS: none 145** 146** FUNCTION VALUE: void 147** 148** SIDE EFFECTS: none 149** 150**-- 151**/ 152 153PUBLIC void twr_dnet_lower_flrs_from_sa 154( 155 sockaddr_p_t sa, 156 twr_p_t *lower_flrs, 157 unsigned32 *status 158) 159{ 160 unsigned8 protocol_id[TWR_C_NUM_DNA_LOWER_FLRS]; 161 unsigned16 floor_count, 162 id_size = twr_c_tower_prot_id_size, 163 related_data_size[TWR_C_NUM_DNA_LOWER_FLRS], 164 twr_rep_16; 165 unsigned32 count, 166 twr_t_length, 167 *related_data_ptr[TWR_C_NUM_DNA_LOWER_FLRS]; 168 byte_p_t tmp_tower; 169 170 CODING_ERROR (status); 171 RPC_VERIFY_INIT (); 172 173 if (sa->family == RPC_C_NAF_ID_DNET) 174 { 175 protocol_id[0] = TWR_C_FLR_PROT_ID_DNA; 176 protocol_id[1] = TWR_C_FLR_PROT_ID_NSP; 177 protocol_id[2] = TWR_C_FLR_PROT_ID_ROUTING; 178 179 /* 180 * Since we now know the socket address we're dealing with, 181 * collect the sizes of each field to allocate memory, and 182 * remember the pointers to the fields so we can copy the 183 * data once we have allocated the tower string. 184 */ 185 186 floor_count = TWR_C_NUM_DNA_LOWER_FLRS; 187 188 related_data_size[0] = 189 sizeof(((struct sockaddr_dn *)sa)->sdn_objnum) + 190 sizeof(((struct sockaddr_dn *)sa)->sdn_objnamel) + 191 ((struct sockaddr_dn *)sa)->sdn_objnamel; 192 193 related_data_ptr[0] = 194 (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_objnum); 195 196 /* do we need to store flags ??? 197 * related_data_size[1] = 198 * sizeof(((struct sockaddr_dn *)sa)->sdn_flags); 199 */ 200 related_data_size[1] = 0; 201 202 related_data_ptr[1] = 203 (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_flags); 204 205 related_data_size[2] = 206 sizeof(((struct sockaddr_dn *)sa)->sdn_add.a_len) + 207 ((struct sockaddr_dn *)sa)->sdn_add.a_len; 208 209 related_data_ptr[2] = 210 (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_add); 211 } 212 else 213 { 214 *status = twr_s_unknown_sa; 215 return; 216 } 217 218 /* 219 * Allocate memory and copy the data into the proper 220 * locations in each of up to three floors. 221 */ 222 223 /* 224 * Calculate length of tower floor. 225 */ 226 227 twr_t_length = twr_c_tower_flr_count_size; /* to store floor count */ 228 229 for ( count = 0; count < floor_count; count++ ) 230 { 231 twr_t_length += TWR_C_FLR_OVERHEAD; 232 twr_t_length += related_data_size[count]; 233 } 234 235 /* 236 * Next allocate space for the tower structure 237 */ 238 RPC_MEM_ALLOC ( 239 *lower_flrs, 240 twr_p_t, 241 sizeof (twr_t) + (twr_t_length - 1), 242 RPC_C_MEM_TOWER, 243 RPC_C_MEM_WAITOK ); 244 245 /* 246 * Copy the length of the tower octet string into the tower structure 247 */ 248 (*lower_flrs)->tower_length = twr_t_length; 249 250 /* 251 * Copy the floor information into the tower octet string 252 */ 253 254 /* 255 * Use a temporary for the octet string since we need 256 * to increment the pointer. 257 */ 258 tmp_tower = (*lower_flrs)->tower_octet_string; 259 260 /* 261 * Copy the number of floors into the tower octet string 262 */ 263 twr_rep_16 = floor_count; 264 RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); 265 memcpy ((char *)tmp_tower, (char *)&twr_rep_16, 266 twr_c_tower_flr_count_size); 267 268 tmp_tower += twr_c_tower_flr_count_size; 269 270 /* 271 * Convert the protocol identifier size to its proper 272 * representation for use in the following loop. 273 */ 274 RPC_RESOLVE_ENDIAN_INT16 (id_size); 275 276 for (count = 0; count < floor_count; count++) 277 { 278 /* 279 * Copy the length of the protocol identifier field into 280 * tower octet string. (Converted before the loop.) 281 */ 282 memcpy ((char *)tmp_tower, (char *)&id_size, 283 TWR_C_TOWER_FLR_LHS_COUNT_SIZE); 284 285 tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; 286 287 /* 288 * Copy the protocol identifier into tower octet string 289 * (1 byte so no need to convert endian representation). 290 */ 291 memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), 292 twr_c_tower_prot_id_size); 293 294 tmp_tower += twr_c_tower_prot_id_size; 295 296 /* 297 * Copy the length of the address data field into 298 * tower octet string. 299 */ 300 twr_rep_16 = related_data_size[count]; 301 RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); 302 memcpy ((char *)tmp_tower, (char *)&twr_rep_16, 303 TWR_C_TOWER_FLR_RHS_COUNT_SIZE); 304 305 tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; 306 307 /* 308 * If there is addressing data, copy the address data field into 309 * tower octet string 310 */ 311 if (related_data_size[count]) 312 { 313 memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], 314 related_data_size[count] ); 315 316 /* 317 * Set up for the next floor. 318 */ 319 tmp_tower += related_data_size[count]; 320 } 321 } 322 323 *status = twr_s_ok; 324} 325 326/* 327**++ 328** 329** ROUTINE NAME: twr_dnet_lower_flrs_to_sa 330** 331** SCOPE: PUBLIC - declared in twr.idl 332** 333** DESCRIPTION: 334** 335** Creates a DECnet sockaddr from the canonical representation of a 336** DECnet protocol tower's lower floors. 337** 338** INPUTS: 339** 340** tower_octet_string 341** The protocol tower to convert to a sockaddr. 342** 343** INPUTS/OUTPUTS: none 344** 345** OUTPUTS: 346** 347** sa Returns a pointer to the created sockaddr structure. 348** 349** sa_len Returns the length, in bytes, of the returned 350** "sa" argument. 351** 352** status A value indicating the return status of the routine: 353** twr_s_ok 354** twr_s_unknown_tower 355** 356** IMPLICIT INPUTS: none 357** 358** IMPLICIT OUTPUTS: none 359** 360** FUNCTION VALUE: void 361** 362** SIDE EFFECTS: none 363** 364**-- 365**/ 366 367PUBLIC void twr_dnet_lower_flrs_to_sa 368( 369 byte_p_t tower_octet_string, 370 sockaddr_p_t *sa, 371 unsigned32 *sa_len, 372 unsigned32 *status 373) 374{ 375 unsigned8 id; 376 byte_p_t tower; 377 unsigned16 count, 378 floor_count, 379 id_size, 380 addr_size; 381 unsigned32 length; 382 383 CODING_ERROR (status); 384 RPC_VERIFY_INIT (); 385 386 id_size = 0; 387 388 /* 389 * make sure we have a pointer to some data structure 390 */ 391 if ( !(tower = tower_octet_string)) 392 { 393 *status = twr_s_unknown_tower; 394 return; 395 } 396 397 /* 398 * Get the tower floor count 399 */ 400 memcpy ((char *)&floor_count, (char *)tower, twr_c_tower_flr_count_size); 401 RPC_RESOLVE_ENDIAN_INT16 (floor_count); 402 403 tower += twr_c_tower_flr_count_size; 404 405 /* 406 * Skip over the (application's) upper floors while we look for the 407 * beginning of the dnet-specific lower floors. 408 */ 409 for (count = 0; count < floor_count; count++) 410 { 411 /* 412 * Get the length of this floor's protocol id field (don't 413 * advance the pointer). 414 */ 415 memcpy ((char *)&id_size, (char *)tower, 416 TWR_C_TOWER_FLR_LHS_COUNT_SIZE); 417 RPC_RESOLVE_ENDIAN_INT16 (id_size); 418 419 /* 420 * Get the protocol id (don't advance the pointer). 421 * Expect one byte; no need to convert. 422 */ 423 memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), 424 twr_c_tower_prot_id_size); 425 426 /* 427 * See if we support the protocol id. 428 */ 429 if ( (id_size == twr_c_tower_prot_id_size) && 430 (id == TWR_C_FLR_PROT_ID_DNA) ) 431 { 432 /* 433 * Indicate we found the beginning of the dnet floors. 434 */ 435 *status = twr_s_ok; 436 437 break; 438 } 439 else 440 { 441 /* 442 * Skip this floor. Get the address size in order 443 * to know how much to skip. 444 */ 445 memcpy ((char *)&addr_size, 446 (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + 447 id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); 448 RPC_RESOLVE_ENDIAN_INT16 (addr_size); 449 450 tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + 451 TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; 452 453 /* 454 * For now, assume we don't find the floors we're looking for. 455 */ 456 *status = twr_s_unknown_tower; 457 } 458 } 459 460 if (*status != twr_s_ok) 461 { 462 return; 463 } 464 465 /* 466 * Skip the floor's protocol id field length and protocol id 467 * (now move the pointer). We already know it's TWR_C_FLR_PROT_ID_DNA. 468 */ 469 tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); 470 471 /* 472 * Allocate space for a DECnet sockaddr 473 */ 474 length = sizeof(struct sockaddr_dn); 475 476 RPC_MEM_ALLOC ( 477 *sa, 478 sockaddr_p_t, 479 length, 480 RPC_C_MEM_SOCKADDR, 481 RPC_C_MEM_WAITOK ); 482 483 *sa_len = length; 484 485 /* 486 * make sure unused bytes are null 487 */ 488 memset ((char *) *sa, 0, length); 489 490 /* 491 * define this as a DECnet family socket 492 */ 493 ((struct sockaddr_dn *)(*sa))->sdn_family = RPC_C_NAF_ID_DNET; 494 495 /* 496 * Length of end user spec 497 */ 498 memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); 499 RPC_RESOLVE_ENDIAN_INT16 (addr_size); 500 tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; 501 502 /* 503 * End user spec 504 */ 505 memcpy (&((struct sockaddr_dn *)(*sa))->sdn_objnum, 506 (char *)tower, 507 addr_size); 508 509 tower += addr_size; 510 511 /* 512 * Length of host transport 513 */ 514 memcpy ((char *)&id_size, (char *)tower, 515 TWR_C_TOWER_FLR_LHS_COUNT_SIZE); 516 RPC_RESOLVE_ENDIAN_INT16 (id_size); 517 tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; 518 519 /* 520 * Transport id 521 * Expect one byte; no need to convert. 522 */ 523 memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); 524 tower += id_size; 525 526 if ((id_size != twr_c_tower_prot_id_size) || 527 (id != TWR_C_FLR_PROT_ID_NSP)) 528 { 529 *status = twr_s_unknown_tower; 530 531 RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); 532 533 return; 534 } 535 536 /* 537 * Length of sdn_flags 538 */ 539 memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); 540 RPC_RESOLVE_ENDIAN_INT16 (addr_size); 541 tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; 542 543 /* 544 * this field is probably null 545 */ 546 if (addr_size) 547 { 548 memcpy ( &((struct sockaddr_dn *)(*sa))->sdn_flags, 549 (char *)tower, 550 addr_size); 551 552 tower += addr_size; 553 } 554 555 /* 556 * Length of routing id 557 */ 558 memcpy ((char *)&id_size, (char *)tower, 559 TWR_C_TOWER_FLR_LHS_COUNT_SIZE); 560 RPC_RESOLVE_ENDIAN_INT16 (id_size); 561 tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; 562 563 /* 564 * Protocol id 565 * Expect one byte, so no need to convert. 566 */ 567 memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); 568 tower += id_size; 569 570 if ( (id_size != twr_c_tower_prot_id_size) || 571 (id != TWR_C_FLR_PROT_ID_ROUTING) ) 572 { 573 *status = twr_s_unknown_tower; 574 575 RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); 576 577 return; 578 } 579 580 /* 581 * the length of host address 582 */ 583 memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); 584 RPC_RESOLVE_ENDIAN_INT16 (addr_size); 585 tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; 586 587 memcpy (&((struct sockaddr_dn *)(*sa))->sdn_add, 588 (char *)tower, 589 addr_size); 590 591 *status = twr_s_ok; 592} 593#else 594static int _naf_dnet_dummy_ = 0 ; 595#endif /* NAF_DNET */ 596