📄 rsvp_maps.c
字号:
intrsvp_pkt_map(struct packet *pkt){ int rerrno = PKT_OK; packet_map *mapp = pkt->pkt_map; /* If this packet was received from the network (ie if it is * in NET byte order), do basic input processing. Otherwise, * it came from API and the map is already built. * * Verify version number and RSVP checksum, and discard * message if any mismatch is found. * * Parse packet and construct map, converting objects to host * byte order. Note that rsvp_map_packet() call may do mallocs * for policy or unknown class objects. */ if (pkt->pkt_order == BO_NET) { memset((char *) mapp, 0, sizeof(packet_map)); rerrno = check_version_sum(pkt); if (rerrno != PKT_OK) return(rerrno); rerrno = rsvp_map_packet(pkt); } return(rerrno);}/* * rsvp_map_packet(): Given input packet and map vector pointed to * by packet structure, parse the packet and build a map of * it, converting the packet to host byte order as we go. * Returns PKT_OK (0) or negative PKT_ERR_.... or positive * errno (if unknown object class). */staticintrsvp_map_packet(struct packet *pkt) { common_header *hdrp = pkt->pkt_data; packet_map *mapp = pkt->pkt_map; char *end_of_data = (char *) pkt->pkt_data + pkt->pkt_len; Object_header *objp; style_t optvec = 0; FlowDesc *flwdp = NULL; SenderDesc *sdscp = SenderDesc_of(pkt); FLOWSPEC *Last_specp = NULL; Fobject *Fobjp; mapp->rsvp_msgtype = RSVP_TYPE_OF(pkt->pkt_data); if ((mapp->rsvp_msgtype < 1) || (mapp->rsvp_msgtype > RSVP_MAX_MSGTYPE)) return(PKT_ERR_MSGTYPE); objp = (Object_header *) (hdrp + 1); while (objp < (Object_header *)end_of_data) {#if BYTE_ORDER == LITTLE_ENDIAN ntoh_object(objp);#endif if ((Obj_Length(objp)&3) || Obj_Length(objp)<4 || (char *)Next_Object(objp) > end_of_data){ return PKT_ERR_OBJLEN; } switch (Obj_Class(objp)) { case class_NULL: /* Ignore it */ break;#ifdef RSVP_DIAGS case class_DIAGNOSTIC: mapp->rsvp_diag = (DIAGNOSTIC *) objp; break; case class_ROUTE: mapp->rsvp_route = (ROUTE *) objp; break; case class_DIAG_RESPONSE: if(!mapp->rsvp_diag_response) mapp->rsvp_diag_response = (DIAG_RESPONSE *)objp; mapp->rsvp_resplist++; break;#endif case class_SESSION: mapp->rsvp_session = (SESSION *) objp; break;/*********** OBSOLETE case class_SESSION_GROUP: mapp->rsvp_sess_grp = (SESSION_GROUP *) objp; break;***********/ case class_RSVP_HOP: mapp->rsvp_hop = (RSVP_HOP *) objp; break; case class_INTEGRITY: mapp->rsvp_integrity = (INTEGRITY *) objp; break; case class_TIME_VALUES: mapp->rsvp_timev = (TIME_VALUES *) objp; break; case class_ERROR_SPEC: mapp->rsvp_errspec = (ERROR_SPEC *) objp; break; case class_SCOPE: mapp->rsvp_scope_list = (SCOPE *) objp; break; case class_STYLE: if (!IsResv(mapp)) return PKT_ERR_BADOBJ; mapp->rsvp_style = (STYLE *) objp; optvec = Style(pkt); break; case class_FLOWSPEC: /* Each flowspec begins new flow descriptor */ if (!IsResv(mapp)) return PKT_ERR_BADOBJ; flwdp = &mapp->rsvp_list[mapp->rsvp_nlist].Resv_list; Last_specp = flwdp->rsvp_specp = (FLOWSPEC *)objp; flwdp->rsvp_filtp = NULL; break; case class_FILTER_SPEC: if (!IsResv(mapp)) return PKT_ERR_BADOBJ; flwdp = &mapp->rsvp_list[mapp->rsvp_nlist++].Resv_list; flwdp->rsvp_filtp = (FILTER_SPEC *)objp; if (flwdp->rsvp_specp == NULL && mapp->rsvp_msgtype != RSVP_RESV_TEAR) { if (mapp->rsvp_nlist == 0) return PKT_ERR_ORDER; /* First must be flowspec */ if (optvec == STYLE_FF) flwdp->rsvp_specp = Last_specp; /* FF: Flowspec ellided -- use last */ } flwdp = &mapp->rsvp_list[mapp->rsvp_nlist].Resv_list; flwdp->rsvp_specp = NULL; break; case class_SENDER_TEMPLATE: if (!IsPath(mapp)) return PKT_ERR_BADOBJ; if (mapp->rsvp_nlist > 0) return PKT_ERR_BADOBJ; mapp->rsvp_nlist = 1; sdscp->rsvp_stempl = (SENDER_TEMPLATE *) objp; break; case class_SENDER_TSPEC: if (!IsPath(mapp)) return PKT_ERR_BADOBJ; /* Could test for duplicate Sender_Tspec or Adspec... * instead, just take the last one that is found. */ sdscp->rsvp_stspec = (SENDER_TSPEC *) objp; break; case class_ADSPEC: if (!IsPath(mapp)) return PKT_ERR_BADOBJ; sdscp->rsvp_adspec = (ADSPEC *) objp; break; case class_POLICY_DATA: /* Save policy objects in list of framed objects */ Fobjp = copy_obj2Fobj(objp); if (!Fobjp) { Log_Mem_Full("PD obj"); break; } FQins(Fobjp, &mapp->rsvp_dpolicy); break; case class_CONFIRM: mapp->rsvp_confirm = (CONFIRM *) objp; break; default: /* Unknown object class. Look at high-order * bits to decide what to do. */ switch (Obj_Class(objp) & UNKN_CLASS_MASK) { case 0x00: case 0x40: /* Reject message. Return * code, val=(class,ctype) */ return (Set_Errno(RSVP_Err_UNKN_OBJ_CLASS, ((Obj_Class(objp)<<8)|Obj_CType(objp)))); case 0x80: /* Ignore object */ break; case 0xc0: /* Save and forward object. Copy it into * a framed object and add to end of list. */ Fobjp = copy_obj2Fobj(objp); if (!Fobjp) { Log_Mem_Full("Unk Class obj"); break; } FQins(Fobjp, &mapp->rsvp_UnkObjList); break; } log(LOG_WARNING, 0, "Unknown class %d ctype %d\n", Obj_Class(objp), Obj_CType(objp)); break; } objp = Next_Object(objp); } if (objp != (Object_header *)end_of_data) { log(LOG_WARNING, 0, "Hdr len err: %d\n", (char *)objp - (char *) end_of_data); return PKT_ERR_LENGTH; } pkt->pkt_order = BO_HOST; if (!(mapp->rsvp_session)) return PKT_ERR_NOSESS; /* * Do style-dependent processing of Resv-type msg */ if (IsResv(mapp)) { switch (optvec) { case 0: /* Error: missing style */ return PKT_ERR_NOSTYLE; case STYLE_WF: if (flwdp) { /* Found a flowspec => msg not empty */ mapp->rsvp_nlist = 1; flwdp->rsvp_filtp = NULL; } break; case STYLE_SE: case STYLE_FF: break; default: /* Error message sent at higher level */ break; } } return PKT_OK;}/* * Compute TCP/UDP/IP checksum. * See p. 7 of RFC-1071. */staticu_int16_tin_cksum(u_int8_t *bp, int n){ u_int16_t *sp = (u_int16_t *) bp; u_int32_t sum = 0; /* Sum half-words */ while (n>1) { sum += *sp++; n -= 2; } /* Add left-over byte, if any */ if (n>0) sum += * (char *) sp; /* Fold 32-bit sum to 16 bits */ sum = (sum & 0xFFFF) + (sum >> 16); sum = ~(sum + (sum >> 16)) & 0xFFFF; if (sum == 0xffff) sum = 0; return (u_int16_t)sum;}#ifndef SECURITYstaticintcheck_integrity(struct packet *pkt) { return(1);}/* * set_integrity() * Initialize INTEGRITY object, if one is required, for * sending packet through specified vif. */staticvoidset_integrity(struct packet *pkt, int vif, net_addr *scrp) {}/* * fin_integrity() * Compute crypto digest over given packet and complete * the INTEGRITY object. */staticvoidfin_integrity(struct packet *pkt) {}#endif /* SECURITY */voidnet_error(net_error_type type,char *s){ switch (type) { case NET_ERROR_SYSTEM: log(LOG_ERR,errno,s); return; case NET_ERROR_USER: default: log(LOG_INFO,0,s); return; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -