/* * @(#) $Id: rapi_bord.c,v 4.2 1998/07/20 18:54:48 lindell Exp $ */ /************************ rapi_bord.c **************************** * * * Routines to convert byte order in rapi interface. * * * * (These routine contain guts of routines in rsvp_spec.c; the * * latter should be changed to use these routines. ) * * * *****************************************************************/ /*****************************************************************************/ /* */ /* RSVPD -- ReSerVation Protocol Daemon */ /* */ /* USC Information Sciences Institute */ /* Marina del Rey, California */ /* */ /* Original Version: Shai Herzog, Nov. 1993. */ /* Current Version: Steven Berson & Bob Braden, May 1996. */ /* */ /* Copyright (c) 1996 by the University of Southern California */ /* All rights reserved. */ /* */ /* Permission to use, copy, modify, and distribute this software and */ /* its documentation in source and binary forms for any purpose and */ /* without fee is hereby granted, provided that both the above */ /* copyright notice and this permission notice appear in all copies, */ /* and that any documentation, advertising materials, and other */ /* materials related to such distribution and use acknowledge that */ /* the software was developed in part by the University of Southern */ /* California, Information Sciences Institute. The name of the */ /* University may not be used to endorse or promote products derived */ /* from this software without specific prior written permission. */ /* */ /* */ /* THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about */ /* the suitability of this software for any purpose. THIS SOFTWARE IS */ /* PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, */ /* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "rsvp_daemon.h" #include "rsvp_api.h" #ifdef STANDARD_C_LIBRARY # include # include /* for offsetof */ #else # include # include #endif /* Endian conversions for Integrated Services headers * */ #define NTOH_IS_Main_Hdr(p) NTOH16((p)->ismh_len32b) #define NTOH_IS_Serv_Hdr(p) NTOH16((p)->issh_len32b) #define NTOH_IS_Parm_Hdr(p) NTOH16((p)->isph_len32b) #define HTON_IS_Main_Hdr(p) HTON16((p)->ismh_len32b) #define HTON_IS_Parm_Hdr(p) HTON16((p)->isph_len32b) #define HTON_IS_Serv_Hdr(p) HTON16((p)->issh_len32b) /* * Forward declarations */ int hton_rapi_flowspec(IS_specbody_t *); int ntoh_rapi_flowspec(IS_specbody_t *); int hton_rapi_tspec(IS_tspbody_t *); int ntoh_rapi_tspec(IS_tspbody_t *); int hton_rapi_adspec(IS_adsbody_t *); int ntoh_rapi_adspec(IS_adsbody_t *); int hton_rapi_genparm(); int ntoh_rapi_genparm(); /* * ntoh_rapi_flowspec(): Convert body of a flowspec or tspec from network * byte order into host byte order. Return -1 if any format error. */ int ntoh_rapi_flowspec(IS_specbody_t *specp) { IS_serv_hdr_t *sp; NTOH_IS_Main_Hdr(&specp->spec_mh); if (!Intserv_Version_OK(&specp->spec_mh)) return -1; sp = (IS_serv_hdr_t *) &specp->spec_u; NTOH_IS_Serv_Hdr(sp); switch (sp->issh_service) { case GUARANTEED_SERV: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ Guar_flowspec_t *gp = (Guar_flowspec_t *) sp; /* Don't convert invalid fields */ if (gp->Gspec_T_flags & ISPH_FLG_INV || gp->Gspec_R_flags & ISPH_FLG_INV) return 0; NTOH_IS_Parm_Hdr(&gp->Guar_Tspec_hdr); NTOH_IS_Parm_Hdr(&gp->Guar_Rspec_hdr); NTOHF32(gp->Gspec_b); NTOHF32(gp->Gspec_r); NTOHF32(gp->Gspec_p); NTOH32(gp->Gspec_m); NTOH32(gp->Gspec_M); NTOHF32(gp->Gspec_R); NTOH32(gp->Gspec_S); #endif } break; case CONTROLLED_LOAD_SERV: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ CL_flowspec_t *clp = (CL_flowspec_t *) sp; /* Don't convert invalid fields */ if (clp->CLspec_flags & ISPH_FLG_INV) return 0; NTOH_IS_Parm_Hdr(&clp->CL_spec_parm_hdr); NTOHF32(clp->CLspec_b); NTOHF32(clp->CLspec_r); NTOHF32(clp->CLspec_p); NTOH32(clp->CLspec_m); NTOH32(clp->CLspec_M); #endif } break; case GENERAL_INFO: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ gen_Tspec_t *gp = (gen_Tspec_t *) sp; /* Don't convert invalid fields */ if (gp->gtspec_flags & ISPH_FLG_INV) return 0; NTOH_IS_Parm_Hdr(&gp->gen_Tspec_parm_hdr); NTOHF32(gp->gtspec_b); NTOHF32(gp->gtspec_r); NTOHF32(gp->gtspec_p); NTOH32(gp->gtspec_m); NTOH32(gp->gtspec_M); #endif } break; default: return -1; } return 0; } /* * hton_rapi_flowspec(): Converts flowspec or tspec body from host byte * order into network byte order. Return -1 if any format error. */ int hton_rapi_flowspec(IS_specbody_t *specp) { IS_serv_hdr_t *sp; if (!Intserv_Version_OK(&specp->spec_mh)) return -1; HTON_IS_Main_Hdr(&specp->spec_mh); sp = (IS_serv_hdr_t *) &specp->spec_u; HTON_IS_Serv_Hdr(sp); switch (sp->issh_service) { case GUARANTEED_SERV: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ Guar_flowspec_t *gp = (Guar_flowspec_t *) sp; /* Don't convert invalid fields */ if (gp->Gspec_T_flags & ISPH_FLG_INV || gp->Gspec_R_flags & ISPH_FLG_INV) return 0; HTON_IS_Parm_Hdr(&gp->Guar_Tspec_hdr); HTONF32(gp->Gspec_b); HTONF32(gp->Gspec_r); HTONF32(gp->Gspec_p); HTON32(gp->Gspec_m); HTON32(gp->Gspec_M); HTON_IS_Parm_Hdr(&gp->Guar_Rspec_hdr); HTONF32(gp->Gspec_R); HTON32(gp->Gspec_S); #endif } break; case CONTROLLED_LOAD_SERV: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ CL_flowspec_t *clp = (CL_flowspec_t *) sp; /* Don't convert invalid fields */ if (clp->CLspec_flags & ISPH_FLG_INV) return 0; HTON_IS_Parm_Hdr(&clp->CL_spec_parm_hdr); HTONF32(clp->CLspec_b); HTONF32(clp->CLspec_r); HTONF32(clp->CLspec_p); HTON32(clp->CLspec_m); HTON32(clp->CLspec_M); #endif } break; case GENERAL_INFO: { #if BYTE_ORDER == LITTLE_ENDIAN /* Avoid compiler warning msg */ gen_Tspec_t *gp = (gen_Tspec_t *) sp; /* Don't convert invalid fields */ if (gp->gtspec_flags & ISPH_FLG_INV) return 0; HTON_IS_Parm_Hdr(&gp->gen_Tspec_parm_hdr); HTONF32(gp->gtspec_b); HTONF32(gp->gtspec_r); HTONF32(gp->gtspec_p); HTON32(gp->gtspec_m); HTON32(gp->gtspec_M); #endif } break; default: return -1; } return 0; } int hton_rapi_adspec(IS_adsbody_t *adsp) { IS_main_hdr_t *mhp = (IS_main_hdr_t *) adsp; IS_serv_hdr_t *shp = (IS_serv_hdr_t *) (mhp+1); IS_serv_hdr_t *lastshp; IS_parm_hdr_t *php, *lastphp, *cphp; lastshp = (IS_serv_hdr_t *) Next_Main_Hdr(mhp); while (shp < lastshp) { /* * For each service fragment... */ lastphp = (IS_parm_hdr_t *)Next_Serv_Hdr(shp); switch (shp->issh_service) { case GENERAL_INFO: php = (IS_parm_hdr_t *)(shp+1); break; case GUARANTEED_SERV: { Gads_parms_t *gap = (Gads_parms_t *) shp; if (shp->issh_len32b == 0) { php = (IS_parm_hdr_t *)(shp+1); break; } HTON_IS_Parm_Hdr(&gap->Gads_Ctot_hdr); HTON32(gap->Gads_Ctot); HTON_IS_Parm_Hdr(&gap->Gads_Dtot_hdr); HTON32(gap->Gads_Dtot); HTON_IS_Parm_Hdr(&gap->Gads_Csum_hdr); HTON32(gap->Gads_Csum); HTON_IS_Parm_Hdr(&gap->Gads_Dsum_hdr); HTON32(gap->Gads_Dsum); php = (IS_parm_hdr_t *)(gap+1); break; } case CONTROLLED_LOAD_SERV: php = (IS_parm_hdr_t *)(shp+1); break; default: /* XXX ?? */ return -1; } /* * Loop to convert general characterization parms, * either default or override. */ while (php < lastphp) { if (hton_rapi_genparm(php) < 0) return -1; php = Next_Parm_Hdr(cphp = php); HTON_IS_Parm_Hdr(cphp); } /* * Continue with next service fragment, if any... */ HTON_IS_Serv_Hdr(shp); shp = (IS_serv_hdr_t *)php; } HTON_IS_Main_Hdr(mhp); return 0; } int ntoh_rapi_adspec(IS_adsbody_t *adsp) { IS_main_hdr_t *mhp = (IS_main_hdr_t *) adsp; IS_serv_hdr_t *shp = (IS_serv_hdr_t *) (mhp+1); IS_serv_hdr_t *lastshp; IS_parm_hdr_t *php, *lastphp; NTOH_IS_Main_Hdr(mhp); lastshp = (IS_serv_hdr_t *) Next_Main_Hdr(mhp); while (shp < lastshp) { /* * For each service fragment... */ NTOH_IS_Serv_Hdr(shp); lastphp = (IS_parm_hdr_t *)Next_Serv_Hdr(shp); switch (shp->issh_service) { case GENERAL_INFO: php = (IS_parm_hdr_t *)(shp+1); break; case GUARANTEED_SERV: { Gads_parms_t *gap = (Gads_parms_t *) shp; if (shp->issh_len32b == 0) { php = (IS_parm_hdr_t *)(shp+1); break; } NTOH_IS_Parm_Hdr(&gap->Gads_Ctot_hdr); NTOH32(gap->Gads_Ctot); NTOH_IS_Parm_Hdr(&gap->Gads_Dtot_hdr); NTOH32(gap->Gads_Dtot); NTOH_IS_Parm_Hdr(&gap->Gads_Csum_hdr); NTOH32(gap->Gads_Csum); NTOH_IS_Parm_Hdr(&gap->Gads_Dsum_hdr); NTOH32(gap->Gads_Dsum); php = (IS_parm_hdr_t *)(gap+1); break; } case CONTROLLED_LOAD_SERV: lastphp = (IS_parm_hdr_t *)Next_Serv_Hdr(shp); php = (IS_parm_hdr_t *)(shp+1); break; default: return -1; break; } /* * Loop to convert general characterization parms, * either default or override. */ while (php < lastphp) { NTOH_IS_Parm_Hdr(php); if (ntoh_rapi_genparm(php) < 0) return -1; php = Next_Parm_Hdr(php); } /* * Continue with next service fragment, if any... */ shp = (IS_serv_hdr_t *)php; } return 0; } int hton_rapi_genparm(IS_parm_hdr_t *pp) { switch (pp->isph_parm_num) { case IS_WKP_HOP_CNT: case IS_WKP_MIN_LATENCY: case IS_WKP_COMPOSED_MTU: HTON32(*(u_int32_t *)(pp+1)); break; case IS_WKP_PATH_BW: HTONF32(*(float32_t *)(pp+1)); break; default: return -1; } return 0; } int ntoh_rapi_genparm(IS_parm_hdr_t *pp) { switch (pp->isph_parm_num) { case IS_WKP_HOP_CNT: case IS_WKP_MIN_LATENCY: case IS_WKP_COMPOSED_MTU: NTOH32(*(u_int32_t *)(pp+1)); break; case IS_WKP_PATH_BW: NTOHF32(*(float32_t *)(pp+1)); break; default: return -1; } return 0; } /**** Currently, filter specs are kept entirely in network byte order, do the following routines are not used. This means that the GPI must be presented by the application in network order. ****/ int hton_rapi_filter(rapi_filter_t *filtp) { switch (filtp->form) { case RAPI_FILTERFORM_BASE: /* sockaddr_in is in network BO */ break; case RAPI_FILTERFORM_GPI: HTON32(filtp->filt_u.gpi.gpi); break; #ifdef USE_IPV6 case RAPI_FILTERFORM_BASE6: /* Already in network BO */ break; case RAPI_FILTERFORM_GPI6: HTON32(filtp->filt_u.gpi6.gpi); break; #endif /* USE_IPV6 */ default: return -1; } return 0; } int ntoh_rapi_filter(rapi_filter_t *filtp) { switch (filtp->form) { case RAPI_FILTERFORM_BASE: /* sockaddr_in is in network BO */ break; case RAPI_FILTERFORM_GPI: NTOH32(filtp->filt_u.gpi.gpi); break; #ifdef USE_IPV6 case RAPI_FILTERFORM_BASE6: /* Already in network BO */ break; case RAPI_FILTERFORM_GPI6: NTOH32(filtp->filt_u.gpi6.gpi); break; #endif /* USE_IPV6 */ default: return -1; } return 0; }