📄 rsvp_maps.c
字号:
/* * @(#) $Id: rsvp_maps.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_maps.c ******************************* * * * Packet map and 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. Other copyrights might apply to parts of this software and are so noted when applicable.********************************************************************/#include "rsvp_daemon.h"extern Fobject * copy_obj2Fobj(Object_header *);extern void FQins(Fobject *, Fobject **);extern void FQkill(Fobject **);static int send_msgto(int, net_addr *, net_addr *,struct packet *);static void build_base(struct packet *);static void build_obj2pkt(Object_header *, struct packet *);static int rsvp_map_packet(struct packet *);static int check_version_sum(struct packet *pkt);static u_int16_t in_cksum(u_char *, int);#ifdef SECURITYextern int check_integrity(struct packet *);extern void set_integrity(struct packet *, int);extern void fin_integrity(struct packet *);#else /* SECURITY */static int check_integrity(struct packet *);static void set_integrity(struct packet *, int);static void fin_integrity(struct packet *);#endif /* SECURITY */char *Type_name[] = {"", "PATH ", "RESV ", "PATH-ERR", "RESV-ERR", "PATH-TEAR", "RESV-TEAR", "RCONFIRM", "", "DREQ", "DREP"};/* * build_send_pkt(): Build RSVP message from a given packet map, and send it. */intbuild_send_pkt( int vif, net_addr *to, net_addr *src, struct packet *opkt) { struct packet lpkt, *pkt = &lpkt; char buff[MAX_PKT+IPUDP_HDR_AREA_SIZE]; packet_map *mapp = opkt->pkt_map; FlowDesc *flwdp; SenderDesc *sdscp;#ifdef RSVP_DIAGS DIAG_RESPONSE *resp;#endif int i; assert(opkt->pkt_order == BO_HOST); *pkt = *opkt; /* Local copy of packet struct */ pkt->pkt_data = (common_header *) (buff+IPUDP_HDR_AREA_SIZE); /* If we need an INTEGRITY object, add it to the map and * initialize it. Then build fixed part of packet from map. * Then, if there is INTEGRITY object, point map to object * in packet (whihc must come immediately after common hdr). */ set_integrity(pkt, vif); build_base(pkt); if (mapp->rsvp_integrity) pkt->pkt_map->rsvp_integrity = (INTEGRITY *) (1 + pkt->pkt_data); pkt->pkt_flags &= ~PKTFLG_Send_RA; switch (mapp->rsvp_msgtype) { case RSVP_CONFIRM: /* Confirm: send Router Alert Option */ pkt->pkt_flags |= PKTFLG_Send_RA; case RSVP_RESV: case RSVP_RESV_ERR: case RSVP_RESV_TEAR: switch (Style(pkt)) { case STYLE_WF: flwdp = FlowDesc_of(pkt, 0); build_obj2pkt(Object_of(flwdp->rsvp_specp), pkt); break; case STYLE_FF: for (i= 0; i < mapp->rsvp_nlist; i++) { int size; flwdp = FlowDesc_of(pkt, i); size = FlowDesc_size(flwdp); if (size + pkt->pkt_len > Max_rsvp_msg) { /* This rudimentary semantic fragmentation * code is an obsolete remnant, which is * left here as a place-holder. */ if (send_msgto(vif, to, src, pkt)<0) return(-1); build_base(pkt); } build_obj2pkt(Object_of(flwdp->rsvp_specp), pkt); build_obj2pkt(Object_of(flwdp->rsvp_filtp), pkt); } break; case STYLE_SE: flwdp = FlowDesc_of(pkt, 0); build_obj2pkt(Object_of(flwdp->rsvp_specp), pkt); for (i= 0; i < mapp->rsvp_nlist; i++) { flwdp = FlowDesc_of(pkt, i); build_obj2pkt(Object_of(flwdp->rsvp_filtp), pkt); } break; } break; case RSVP_PATH: case RSVP_PATH_TEAR: /* Path or Path_Tear: send Router Alert Option */ pkt->pkt_flags |= PKTFLG_Send_RA; case RSVP_PATH_ERR: sdscp = SenderDesc_of(pkt); build_obj2pkt(Object_of(sdscp->rsvp_stempl), pkt); build_obj2pkt(Object_of(sdscp->rsvp_stspec), pkt); build_obj2pkt(Object_of(sdscp->rsvp_adspec), pkt); break;#ifdef RSVP_DIAGS case RSVP_DREQ: case RSVP_DREP: if (DIAG_HBIT(mapp->rsvp_diag) == 1) build_obj2pkt(Object_of(pkt->pkt_map->rsvp_route),pkt); resp = mapp->rsvp_diag_response; for (i= 0; i < mapp->rsvp_resplist; i++) { build_obj2pkt(Object_of(resp), pkt); (char *)resp += Obj_Length(resp); } break;#endif default: assert(0); break; } return (send_msgto(vif, to, src, pkt));}/* * send_msgto(): Given an RSVP message, complete its common header, * convert it to network byte order, compute a checksum, and send it. */staticintsend_msgto( int vif, net_addr *to, net_addr *src, struct packet *pkt) { common_header *hdrp = pkt->pkt_data; assert(pkt->pkt_order == BO_HOST); /* * Complete common header and convert to network byte order */ memset((char *)hdrp, 0, sizeof(common_header)); hdrp->rsvp_verflags = RSVP_MAKE_VERFLAGS(RSVP_VERSION, 0); hdrp->rsvp_type = pkt->pkt_map->rsvp_msgtype; hdrp->rsvp_length = pkt->pkt_len; hton_packet(pkt); assert(pkt->pkt_order == BO_NET); /* * Set ttl in common header and, either checksum packet * or, if there is INTEGRITY object, compute digest. */ hdrp->rsvp_snd_TTL = pkt->pkt_ttl; hdrp->rsvp_cksum = 0; if (pkt->pkt_map->rsvp_integrity) fin_integrity(pkt); else hdrp->rsvp_cksum = in_cksum((u_int8_t *)pkt->pkt_data, pkt->pkt_len); return do_sendmsg(vif, to, src, pkt->pkt_flags, pkt->pkt_ttl, (u_char *) pkt->pkt_data, pkt->pkt_len);}/* build_base(): Start building new packet from given map. * * o Initialize pkt len to size of common header; this field * will be used for bookkeeping as the variable part of the * packet is built. * o Copy objects into packet from fixed part of map. * o Copy unknown objects into packet * (Note that we have lost any order information...) * o Set byte order to HOST. */staticvoidbuild_base(struct packet *pkt) { Object_header **mappp, *pktp; Fobject *fobjp; pkt->pkt_len = sizeof(common_header); pktp = (Object_header *) ((common_header *) pkt->pkt_data + 1); mappp = (Object_header **) &pkt->pkt_map->rsvp_diag; while (mappp <= (Object_header **) &pkt->pkt_map->rsvp_style) { if (*mappp) build_obj2pkt(*mappp, pkt); mappp++; } for (fobjp = pkt->pkt_map->rsvp_UnkObjList; fobjp; fobjp = fobjp->Fobj_next) { if (fobjp) build_obj2pkt(&fobjp->Fobj_objhdr, pkt); } pkt->pkt_order = BO_HOST;}/* built_obj2pkt(): Move object *objp into packet buffer at offset * determined from pkt_len field in packet structure, and * advance pkt_len field. */staticvoidbuild_obj2pkt(Object_header *objp, struct packet *pkt) { Object_header *pktp; if (objp && (Object_Size(objp) > 0) ) { pktp = (Object_header *) ((char *) pkt->pkt_data + pkt->pkt_len); move_object(objp, pktp); pkt->pkt_len += Obj_Length(pktp); }}/* Check version and checksum in incoming packet, converting * common header to host byte order in the process. Ignore * zero checksum. */staticintcheck_version_sum(struct packet *pkt) { int pkt_version = RSVP_VERSION_OF(pkt->pkt_data); int rerrno; assert(pkt->pkt_order == BO_NET); /* * Check version, checksum (if non-zero), and length. */ if (pkt_version != RSVP_VERSION) { log(LOG_WARNING, 0, "Bad pkt version #%d\n", pkt_version); return PKT_ERR_VERSION; } if ((pkt->pkt_data->rsvp_cksum) && in_cksum((u_char *) pkt->pkt_data, pkt->pkt_len)) { log(LOG_WARNING, 0, "Checksum error\n"); return PKT_ERR_CKSUM; } /* Make one pass over the raw packet (in network format) stopping * if/when the integrity object is found. Since the integrity * object is one of the first in the packet, this would make an * extra pass over the entire packet only if no integrity object * is included. */ rerrno = check_integrity(pkt); if (rerrno < 0) /* Integrity Error */ return rerrno; NTOH16(pkt->pkt_data->rsvp_length); if (pkt->pkt_data->rsvp_length != pkt->pkt_len) { log(LOG_WARNING, 0, "Pkt length wrong (%u)\n", pkt->pkt_len); return PKT_ERR_LENGTH; } return PKT_OK;}/* * rsvp_pkt_map(): Build packet map from RSVP message. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -