/* * @(#) $Id: rsvp_bord.c,v 4.7 1998/08/17 20:52:30 mtalwar Exp $ */ /************************ rsvp_bord.c ******************************* * * * RSVP daemon: Byte-order routines * * * *********************************************************************/ /**************************************************************************** RSVPD -- ReSerVation Protocol Daemon USC Information Sciences Institute Marina del Rey, California 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. Other copyrights might apply to parts of this software and are so noted when applicable. ********************************************************************/ /* Routines in this file convert RSVP objects between network and * local host formats. * * Currently IP addresses and IP transport level ports are stored * internally in network format. This includes those found inside * filterspecs, sender templates, and scope objects. * All other quantities are stored and processed in the local host format */ #include "rsvp_daemon.h" #include "rsvp_specs.h" #include "rapi_lib.h" /* External declarations */ void hton_flowspec(FLOWSPEC *); void ntoh_flowspec(FLOWSPEC *); void hton_tspec(SENDER_TSPEC *); void ntoh_tspec(SENDER_TSPEC *); void hton_adspec(ADSPEC *); void ntoh_adspec(ADSPEC *); void hton_label(Label *); void ntoh_label(Label *); /* Forward declarations */ void hton_object(Object_header *); void ntoh_object(Object_header *); /* * Convert given packet buffer to network byte order. */ void hton_packet(struct packet *pkt) { #if BYTE_ORDER == LITTLE_ENDIAN common_header *hdrp = pkt->pkt_data; char *lastp = (char *) pkt->pkt_data + pkt->pkt_len; Object_header *objp, *nextp; if (pkt->pkt_order == BO_NET) return; objp = (Object_header *) (hdrp+1); while ( (char *)objp < lastp) { nextp = Next_Object(objp); hton_object(objp); objp = nextp; } /* Common fixed header fields */ /* NB: checksum is not swapped */ HTON16(hdrp->rsvp_length); #endif pkt->pkt_order = BO_NET; } void hton_object(Object_header *objp) { Object_header *op, *nxtp; char *end_of_dresp; switch (Obj_Class(objp)) { case class_NULL: break; case class_DIAGNOSTIC : HTON32(((DIAGNOSTIC *)objp)->diag_msgID); HTON16(((DIAGNOSTIC *)objp)->diag_pMTU); HTON16(((DIAGNOSTIC *)objp)->diag_frag_off); break ; case class_DIAG_RESPONSE : HTON32(((DIAG_RESPONSE *)objp)->resp_arrtime); HTON32(((DIAG_RESPONSE *)objp)->resp_rstyle); HTON16(((DIAG_RESPONSE *)objp)->resp_timeval); /* now "hton_object" the embedded objects * if they exist, they should be in * TSPEC, FLOWSPEC, {FILTER_SPEC,FILTER_SPEC..} * order */ /* tspec */ if (Obj_Length(objp) > DRESP_BASIC_SIZE) { op = (Object_header *)((char *)objp + DRESP_BASIC_SIZE); nxtp = Next_Object(op); hton_object(op); op = nxtp; } /* flowspec */ if (Obj_Length(objp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC)) { nxtp = Next_Object(op); hton_object(op); op = nxtp; } /* variable number of filter specs */ if (Obj_Length(objp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC) + sizeof(FLOWSPEC)) { end_of_dresp = (char *)objp + Obj_Length(objp); while ((char *)op < end_of_dresp) { nxtp = Next_Object(op); hton_object(op); op = nxtp ; } } break ; case class_SESSION: /* addresses and ports stored internally in network order */ break; case class_SESSION_GROUP: /* Not defined. */ break; case class_RSVP_HOP: /* addresses are stored internally in network order */ switch(Obj_CType(objp)) { case ctype_RSVP_HOP_ipv4: HTON32(((RSVP_HOP *)objp)->hop4_LIH); break; #ifdef USE_IPV6 case ctype_RSVP_HOP_ipv6: HTON32(((RSVP_HOP *)objp)->hop6_LIH); break; #endif /* USE_IPV6 */ default: break; } break; case class_INTEGRITY: /* keyid stored internally in network order */ /* message digest stored internally in network order */ HTON32(((INTEGRITY *)objp)->intgr_seqno[0]); HTON32(((INTEGRITY *)objp)->intgr_seqno[1]); break; case class_TIME_VALUES: HTON32(((TIME_VALUES *)objp)->timev_R); break; case class_ERROR_SPEC: /* addresses stored internally in network order */ switch(Obj_CType(objp)) { case ctype_ERROR_SPEC_ipv4: HTON16(((ERROR_SPEC *)objp)->errspec4_value); break; #ifdef USE_IPV6 case ctype_ERROR_SPEC_ipv6: HTON16(((ERROR_SPEC *)objp)->errspec6_value); break; #endif /* USE_IPV6 */ default: break; } break; case class_SCOPE: { /* addresses stored internally in network order */ break; } case class_STYLE: HTON32(((STYLE *)objp)->style_word); break; case class_FLOWSPEC: hton_flowspec((FLOWSPEC *)objp); break; case class_SENDER_TEMPLATE: case class_FILTER_SPEC: /* addresses and ports stored internally in network order */ break; case class_SENDER_TSPEC: hton_tspec((SENDER_TSPEC *)objp); break; case class_ADSPEC: hton_adspec((ADSPEC *)objp); break; case class_POLICY_DATA: /* TBD */ break; case class_CONFIRM: /* addresses stored internally in network order */ break; #if defined (LABEL) case class_Label: hton_label((Label *)objp); break; case class_Label_Request: HTON16(((Labelreq *)objp)->l3pid); break; #endif default: /* If we don't understand this class, we can't convert its * byte order; but that doesn't matter, because it must * have originated elsewhere and must still be in network * byte order. */ break; } HTON16(Obj_Length(objp)); } void ntoh_packet(struct packet *pkt) { #if BYTE_ORDER == LITTLE_ENDIAN common_header *hdrp = pkt->pkt_data; char *lastp = (char *) pkt->pkt_data + pkt->pkt_len; Object_header *objp; if (pkt->pkt_order == BO_HOST) return; objp = (Object_header *) (hdrp+1); while ((char *)objp < lastp) { ntoh_object(objp); objp = Next_Object(objp); } /* Common fixed header fields */ /* NB: checksum is not swapped */ NTOH16(hdrp->rsvp_length); #endif pkt->pkt_order = BO_HOST; } void ntoh_object(Object_header *objp) { char *end_of_dresp; Object_header *op; NTOH16(Obj_Length(objp)); switch (Obj_Class(objp)) { case class_NULL: break; case class_DIAGNOSTIC : NTOH32(((DIAGNOSTIC *)objp)->diag_msgID); NTOH16(((DIAGNOSTIC *)objp)->diag_pMTU); NTOH16(((DIAGNOSTIC *)objp)->diag_frag_off); break ; /* addresses are already in network order */ case class_DIAG_RESPONSE : NTOH32(((DIAG_RESPONSE *)objp)->resp_arrtime); NTOH32(((DIAG_RESPONSE *)objp)->resp_rstyle); NTOH16(((DIAG_RESPONSE *)objp)->resp_timeval); /* now "ntoh_object" the embedded objects * if they exist, they should be in * TSPEC, FLOWSPEC, {FILTER_SPEC,FILTER_SPEC..} * order */ /* tspec */ if (Obj_Length(objp) > DRESP_BASIC_SIZE) { op = (Object_header *)((char *)objp + DRESP_BASIC_SIZE); ntoh_object(op); op = Next_Object(op); } /* flowspec */ if (Obj_Length(objp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC)) { ntoh_object(op); op = Next_Object(op); } /* variable number of filter specs */ if (Obj_Length(objp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC) + sizeof(FLOWSPEC)) { end_of_dresp = (char *)objp + Obj_Length(objp); while ((char *)op < end_of_dresp) { ntoh_object(op); op = Next_Object(op); } } break; case class_SESSION: break; case class_SESSION_GROUP: break; case class_RSVP_HOP: switch(Obj_CType(objp)) { case ctype_RSVP_HOP_ipv4: NTOH32(((RSVP_HOP *)objp)->hop4_LIH); break; #ifdef USE_IPV6 case ctype_RSVP_HOP_ipv6: NTOH32(((RSVP_HOP *)objp)->hop6_LIH); break; #endif /* USE_IPV6 */ default: break; } break; case class_INTEGRITY: NTOH32(((INTEGRITY *)objp)->intgr_seqno[0]); NTOH32(((INTEGRITY *)objp)->intgr_seqno[1]); break; case class_TIME_VALUES: NTOH32(((TIME_VALUES *)objp)->timev_R); break; case class_ERROR_SPEC: switch(Obj_CType(objp)) { case ctype_ERROR_SPEC_ipv4: NTOH16(((ERROR_SPEC *)objp)->errspec4_value); break; #ifdef USE_IPV6 case ctype_ERROR_SPEC_ipv6: NTOH16(((ERROR_SPEC *)objp)->errspec6_value); break; #endif /* USE_IPV6 */ default: break; } break; case class_SCOPE: break; case class_STYLE: NTOH32(((STYLE *)objp)->style_word); break; case class_FLOWSPEC: ntoh_flowspec((FLOWSPEC *)objp); break; case class_SENDER_TEMPLATE: case class_FILTER_SPEC: break; case class_SENDER_TSPEC: ntoh_tspec((SENDER_TSPEC *)objp); break; case class_ADSPEC: ntoh_adspec((ADSPEC *)objp); break; case class_POLICY_DATA: break; case class_CONFIRM: break; #if defined (LABEL) case class_Label: ntoh_label((Label *)objp); break; case class_Label_Request: NTOH16(((Labelreq *)objp)->l3pid); break; #endif default: /* If we don't understand class, leave in network * byte order. */ break; } }