/* * @(#) $Id: rsvp_util.c,v 4.13 1997/09/15 19:48:20 lindell Exp $ */ /************************ rsvp_util.c ******************************* * * * Common routines for managing state and parsing protocol * * data structure (flowspecs, filterspecs, flow descriptors...) * * Used by rsvp_path.c and rsvp_resv.c * * * *********************************************************************/ /**************************************************************************** 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. Other copyrights might apply to parts of this software and are so noted when applicable. ********************************************************************/ #include "rsvp_daemon.h" /* Forward declarations */ Object_header * copy_object(Object_header *); Fobject * copy_obj2Fobj(Object_header *); void FQins(Fobject *, Fobject **); Fobject * FQrmv(Fobject **); void FQconcat(Fobject *, Fobject **); void FQkill(Fobject **); void move_object(Object_header *oldp, Object_header *newp) { int size = Object_Size(oldp); assert((oldp) && (newp) && (size) && (size&3) == 0 ); memcpy((char *) newp, (char *) oldp, size); } Object_header * copy_object(Object_header *oldp) { int size = Object_Size(oldp); Object_header *newp = malloc(size); if (!(oldp)) return(NULL); assert((newp)); move_object(oldp, newp); return(newp); } /* Manipulate framed objects (Fobject's) * */ /* copy_obj2Fobj: Copy object into framed object */ Fobject * copy_obj2Fobj(Object_header *oldp) { int size = Object_Size(oldp) ; Fobject *newp; if (!(oldp)) return(NULL); newp = malloc(size + sizeof(Fobject *)); if (!newp) return(NULL); newp->Fobj_next = NULL; memcpy((char *) &newp->Fobj_objhdr, (char *) oldp, size); return(newp); } /* FQkill: delete list of framed objects. */ void FQkill(Fobject **head) { Fobject *fop; while ((fop = FQrmv(head))) free(fop); } void FQins(Fobject *in, Fobject **head) { in->Fobj_next = *head; *head = in; } Fobject *FQrmv(Fobject **head) { Fobject *topfop = *head; if (topfop) *head = topfop->Fobj_next; return(topfop); } void FQconcat(Fobject *newp, Fobject **head) { Fobject *fop, *fcp; for (fop = newp; fop; fop = fop->Fobj_next) { fcp = copy_obj2Fobj(&fop->Fobj_objhdr); if (!fcp) return; FQins(fcp, head); } } /* merge_UnkObjL2: merge new unknown-object list into target list, * retaining only one copy of each distinct object. * If IsCpy is TRUE, do malloc for Fobjects added to target list and * leave new list unchanged. If ISCpy is FALSE, destroy the new object * list, either moving new objects into the target list or freeing them. */ void merge_UnkObjL2(Fobject **newLpp, Fobject **targLpp, int IsCpy) { Fobject **prevpp, *newp, *fop; Object_header *newobjp; for (prevpp = newLpp; *prevpp; prevpp = &(*prevpp)->Fobj_next) { newp = (*prevpp)->Fobj_next; newobjp = &newp->Fobj_objhdr; for (fop = *targLpp; fop; fop = fop->Fobj_next) { Object_header *tobjp = &fop->Fobj_objhdr; if (Obj_Length(tobjp) == Obj_Length(newobjp) && memcmp((char *)tobjp, (char *)&newobjp, Obj_Length(tobjp)) == 0) break; } if (!fop) { if (IsCpy) FQins(copy_obj2Fobj(newobjp), targLpp); else FQins(FQrmv(prevpp), targLpp); } else if (!IsCpy) free(FQrmv(prevpp)); } } /* Given a consecutive area with room for a packet structure, * a map vector, and a packet buffer, initialize the packet * structure. */ struct packet * new_packet_area(packet_area *pap) { struct packet *pkt = (struct packet *) pap; packet_map *mapp = (packet_map *) (pkt+1); char *buffp = (char *)(mapp+1); common_header *hdrp; pkt->pkt_offset = 0; hdrp = (common_header *)(buffp /* + pkt->pkt_offset */); pkt->pkt_len = 0; pkt->pkt_data = hdrp; /* Addr of msg in buffer */ pkt->pkt_map = mapp; /* Addr of map vector */ pkt->pkt_flags = pkt->pkt_ttl = 0; pkt->pkt_order = BO_HOST; /* Clear packet map */ memset((char *) mapp, 0, sizeof(packet_map)); return(pkt); }