From 2b19e5f2eaf88428dfa2d6f6b578f25327ea9ecc Mon Sep 17 00:00:00 2001 From: "James R. Leu" Date: Wed, 11 Jun 2003 20:41:50 -0600 Subject: [PATCH] More RSVP-TE packet encode decode [git-p4: depot-paths = "//depot/ldp-portable/": change = 370] --- rsvpte/rsvpte_packet.c | 1580 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1580 insertions(+) create mode 100644 rsvpte/rsvpte_packet.c diff --git a/rsvpte/rsvpte_packet.c b/rsvpte/rsvpte_packet.c new file mode 100644 index 0000000..7d326bf --- /dev/null +++ b/rsvpte/rsvpte_packet.c @@ -0,0 +1,1580 @@ +#include "rsvpte_struct.h" + +inline void htonl_nba(u_char * buf, u_int * extra) { + u_int temp; + memcpy(&temp, buf, sizeof(u_int)); + temp = htonl(temp); + memcpy(buf, &temp, sizeof(u_int)); + if (extra) { + (*extra) = temp; + } +} + +inline void ntohl_nba(u_char * buf, u_int * extra) { + u_int temp; + memcpy(&temp, buf, sizeof(u_int)); + temp = ntohl(temp); + memcpy(buf, &temp, sizeof(u_int)); + if (extra) { + (*extra) = temp; + } +} + +inline void htons_nba(u_char * buf, u_short * extra) { + u_short temp; + memcpy(&temp, buf, sizeof(u_short)); + temp = htons(temp); + memcpy(buf, &temp, sizeof(u_short)); + if (extra) { + (*extra) = temp; + } +} + +inline void ntohs_nba(u_char * buf, u_short * extra) { + u_int temp; + memcpy(&temp, buf, sizeof(u_short)); + temp = ntohs(temp); + memcpy(buf, &temp, sizeof(u_short)); + if (extra) { + (*extra) = temp; + } +} + +/* Message Header */ + +int rsvpteEncodeMsgHeader(rsvpHeader_t * header, u_char * buf, int bufSize) { + rsvpHeader_t headerCopy; + + if (RSVP_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + headerCopy = *header; + headerCopy.checksum = htons(header->checksum); + headerCopy.length = htons(header->length); + + memcpy(buf, &headerCopy, RSVP_HDRSIZE); + return RSVP_HDRSIZE; +} + +int rsvpteDecodeMsgHeader(rsvpHeader_t * header, u_char * buf, int bufSize) { + if (RSVP_HDRSIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy((u_char*)header, buf, RSVP_HDRSIZE); + header->checksum = ntohs(header->checksum); + header->length = ntohs(header->length); + + if (header->length > RSVP_PDUMAXLEN) { + return MPLS_PDU_LENGTH_ERROR; + } + return RSVP_HDRSIZE; +} + +/* Object Header */ + +int rsvpteEncodeObjectHeader(rsvpObjectHeader_t * header, u_char * buf, int bufSize) { + rsvpObjectHeader_t headerCopy; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + headerCopy = *header; + headerCopy.length = htons(header->length); + + memcpy(buf, &headerCopy, RSVP_OBJECT_HDRSIZE); + return RSVP_OBJECT_HDRSIZE; +} + +int rsvpteDecodeObjectHeader(rsvpObjectHeader_t * header, u_char * buf, int bufSize) { + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(header, buf, RSVP_OBJECT_HDRSIZE); + header->length = ntohs(header->length); + return RSVP_OBJECT_HDRSIZE; +} + +/* Session Object */ + +int rsvpteEncodeSession4(rsvpSession4_t * session, u_char * buf, int bufSize) { + rsvpSession4_t sessionCopy; + + if (RSVP_SESSION4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + sessionCopy = *session; + + sessionCopy.destAddr = htonl(session->destAddr); + sessionCopy.destPort = htons(session->destPort); + + memcpy(buf, &sessionCopy, RSVP_SESSION4_SIZE); + return RSVP_SESSION4_SIZE; +} + +int rsvpteDecodeSession4(rsvpSession4_t * session, u_char * buf, int bufSize) { + if (RSVP_SESSION4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(session, buf, RSVP_SESSION4_SIZE); + session->destAddr = nthol(session->destAddr); + session->destPort = nthos(session->destPort); + + return RSVP_SESSION4_SIZE; +} + +int rsvpteEncodeSession6(rsvpSession6_t * session, u_char * buf, int bufSize) { + rsvpSession6_t sessionCopy; + if (RSVP_SESSION6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + sessionCopy = *session; + + sessionCopy.destPort = htons(session->destPort); + + memcpy(buf, &sessionCopy, RSVP_SESSION4_SIZE); + return RSVP_SESSION4_SIZE; +} + +int rsvpteDecodeSession6(rsvpSession6_t * session, u_char * buf, int bufSize) { + if (RSVP_SESSION6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(session, buf, RSVP_SESSION4_SIZE); + session->destPort = nthos(session->destPort); + + return RSVP_SESSION4_SIZE; +} + +int rsvpteEncodeSessionTunnel4(rsvpSessionTunnel4_t * session, u_char * buf, int bufSize) { + rsvpSessionTunnel4_t sessionCopy; + if (RSVP_SESSION_TUNNEL4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + sessionCopy = *session; + + sessionCopy.endPointAddress = htonl(session->endPointAddress); + sessionCopy.reserved = 0; + sessionCopy.tunnelId = htons(session->tunnelId); + sessionCopy.extentedTunnelId = htonl(session->destPort); + + memcpy(buf, &sessionCopy, RSVP_SESSION_TUNNEL4_SIZE); + return RSVP_SESSION_TUNNEL4_SIZE; +} + +int rsvpteDecodeSessionTunnel4(rsvpSessionTunnel4_t * session, u_char * buf, int bufSize) { + if (RSVP_SESSION_TUNNEL4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(session, buf, RSVP_SESSION_TUNNEL4_SIZE); + session->endPointAddress = nthol(session->endPointAddress); + session->reserved = nthos(session->reserved); + session->tunnelId = nthos(session->tunnelId); + session->extentedTunnelId = nthol(session->extentedTunnelId); + + return RSVP_SESSION_TUNNEL4_SIZE; +} + +int rsvpteEncodeSessionTunnel6(rsvpSessionTunnel6_t * session, u_char * buf, int bufSize) { + rsvpSessionTunnel6_t sessionCopy; + if (RSVP_SESSION_TUNNEL6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + sessionCopy = *session; + + sessionCopy.reserved = 0; + sessionCopy.tunnelId = htons(session->tunnelId); + + memcpy(buf, &sessionCopy, RSVP_SESSION_TUNNEL6_SIZE); + return RSVP_SESSION_TUNNEL6_SIZE; +} + +int rsvpteDecodeSessionTunnel6(rsvpSessionTunnel6_t * session, u_char * buf, int bufSize) { + if (RSVP_SESSION_TUNNEL6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(session, buf, RSVP_SESSION_TUNNEL6_SIZE); + session->reserved = nthos(session->reserved); + session->tunnelId = nthos(session->tunnelId); + + return RSVP_SESSION_TUNNEL6_SIZE; +} + +int rsvpteEncodeSessionObject(rsvpSessionObject_t * session, u_char * buf, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(session->hdr.cType) { + case RSVP_SESSION_CTYPE_IPV4: + size = rsvpteEncodeSession4(&session->u.ipv4, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_IPV6: + size = rsvpteEncodeSession6(&session->u.ipv6, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_TUNNEL4: + size = rsvpteEncodeSessionTunnel4(&session->u.tunnel4, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_TUNNEL6: + size = rsvpteEncodeSessionTunnel6(&session->u.tunnel6, buf, bufSize); + break; + default: + return RSVP_ENC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + encodeSize += size; + + session->hdr.length = encodeSize; + session->hdr.class = RSVP_SESSION_CLASS; + size = rsvpteEncodeObjectHeader(&session->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); + if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeSessionObject(rsvpSessionObject_t * session, u_char * buf, int bufSize) { + int decodedSize = 0; + + size = rsvpteDecodeObjectHeader(&session->hdr, buf, bufSize); + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (session->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (session->hdr.class != RSVP_SESSION_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(session->hdr.cType) { + case RSVP_SESSION_CTYPE_IPV4: + size = rsvpteDecodeSession4(&session->u.ipv4, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_IPV6: + size = rsvpteDecodeSession6(&session->u.ipv6, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_TUNNEL4: + size = rsvpteDecodeSessionTunnel4(&session->u.tunnel4, buf, bufSize); + break; + case RSVP_SESSION_CTYPE_TUNNEL6: + size = rsvpteDecodeSessionTunnel6(&session->u.tunnel6, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +int rsvpteEncodeHop4(rsvpHop4_t * hop, u_char * buf, int bufSize) { + rsvpHop4_t hopCopy; + if (RSVP_HOP4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + hopCopy = *hop; + + hopCopy.hopAddr = htonl(hop->hopAddr); + hopCopy.logicalIfHandle = htonl(hop->logicalIfHandle); + memcpy(buf, &hopCopy, RSVP_HOP4_SIZE); + + return RSVP_HOP4_SIZE; +} + +int rsvpteDecodeHop4(rsvpHop4_t * hop, u_char * buf, int bufSize) { + if (RSVP_HOP4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(hop, buf, RSVP_HOP4_SIZE); + hop->hopAddr = nthol(hop->hopAddr); + hop->logicalIfHandle = nthol(hop->logicalIfHandle); + + return RSVP_HOP4_SIZE; +} + +int rsvpteEncodeHop6(rsvpHop6_t * hop, u_char * buf, int bufSize) { + rsvpHop6_t hopCopy; + if (RSVP_HOP6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + hopCopy = *hop; + + hopCopy.logicalIfHandle = htonl(hop->logicalIfHandle); + memcpy(buf, &hopCopy, RSVP_HOP6_SIZE); + + return RSVP_HOP6_SIZE; +} + +int rsvpteDecodeHop6(rsvpHop6_t * hop, u_char * buf, int bufSize) { + if (RSVP_HOP6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(hop, buf, RSVP_HOP6_SIZE); + hop->logicalIfHandle = nthol(hop->logicalIfHandle); + + return RSVP_HOP6_SIZE; +} + +int rsvpteEncodeHopObject(rsvpHopObject_t * hop, u_char * buf, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(hop->hdr.cType) { + case RSVP_HOP_CTYPE_IPV4: + size = rsvpteEncodeHop4(&hop->u.ipv4, buf, bufSize); + break; + case RSVP_HOP_CTYPE_IPV6: + size = rsvpteEncodeHop6(&hop->u.ipv6, buf, bufSize); + break; + default: + return RSVP_ENC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + encodeSize += size; + + session->hdr.length = encodeSize; + session->hdr.class = RSVP_HOP_CLASS; + size = rsvpteEncodeObjectHeader(&session->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeHopObject(rsvpHopObject_t * hop, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&session->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (session->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (session->hdr.class != RSVP_HOP_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(session->hdr.cType) { + case RSVP_HOP_CTYPE_IPV4: + size = rsvpteDecodeHop4(&hop->u.ipv4, buf, bufSize); + break; + case RSVP_HOP_CTYPE_IPV6: + size = rsvpteDecodeHop4(&hop->u.ipv6, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +/* Time Object */ + +int rsvpteEncodeTimeObject(rsvpTimeObject_t * time, u_char * buf, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + { + u_int refresh = htonl(time->refresh); + if (RSVP_TIME_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + memcpy(buf, &refresh, RSVP_TIME_SIZE); + size = RSVP_TIME_SIZE; + } + encodeSize += size; + + session->hdr.length = encodeSize; + session->hdr.class = RSVP_TIME_CLASS; + session->hdr.cType = RSVP_TIME_CTYPE; + + size = rsvpteEncodeObjectHeader(&session->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeTimeObject(rsvpTimeObject_t * time, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&session->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (session->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (session->hdr.class != RSVP_TIME_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(time->hdr.cType) { + case RSVP_TIME_CTYPE: + if (RSVP_TIME_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + memcpy(&time->refresh, buf, RSVP_TIME_SIZE); + time->refresh = ntohl(time->refresh); + size = RSVP_TIME_SIZE; + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + return decodeSize + size; +} + +/* Explicit Route Object */ + +int rsvpteEncodeExplicitRoute4(rsvpExplicitRoute4_t * er, u_char * buf, int bufSize) { + rsvpExplicitRoute4_t erCopy; + + if (RSVP_ER4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + erCopy = *er; + + erCopy.flags.mark = htons(er->flags.mark); + htonl_nba(erCopy.address, &erCopy.uIntAddress); + + memcpy(buf, &erCopy, RSVP_ER4_SIZE); + + return RSVP_ER4_SIZE; +} + +int rsvpteDecodeExplicitRoute4(rsvpExplicitRoute4_t * er, u_char * buf, int bufSize) { + if (RSVP_ER4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(er, buf, RSVP_ER4_SIZE); + er->flags.mark = ntohs(er->flags.mark); + ntohl_nba(er->address, &er->uIntAddress); + + return RSVP_ER4_SIZE; +} + +int rsvpteEncodeExplicitRoute6(rsvpExplicitRoute6_t * er, u_char * buf, int bufSize) { + rsvpExplicitRoute6_t erCopy; + + if (RSVP_ER6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + erCopy = *er; + + erCopy.flags.mark = htons(er->flags.mark); + + memcpy(buf, &erCopy, RSVP_ER6_SIZE); + + return RSVP_ER6_SIZE; +} + +int rsvpteDecodeExplicitRoute6(rsvpExplicitRoute6_t * er, u_char * buf, int bufSize) { + if (RSVP_ER6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(er, buf, RSVP_ER6_SIZE); + er->flags.mark = ntohs(er->flags.mark); + + return RSVP_ER6_SIZE; +} + +int rsvpteEncodeExplicitRouteAsn(rsvpExplicitRouteAsn_t * er, u_char * buf, int bufSize) { + rsvpExplicitRouteAsn_t erCopy; + + if (RSVP_ERASN_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + erCopy = *er; + + erCopy.flags.mark = htons(er->flags.mark); + + memcpy(buf, &erCopy, RSVP_ER6_SIZE); + + return RSVP_ERASN_SIZE; +} + +int rsvpteDecodeExplicitRouteAsn(rsvpExplicitRouteAsn_t * er, u_char * buf, int bufSize) { + if (RSVP_ERASN_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(er, buf, RSVP_ERASN_SIZE); + er->flags.mark = ntohs(er->flags.mark); + + return RSVP_ERASN_SIZE; +} + +int rsvpteEncodeExplicitRouteObject(rsvpExplicitRouteObject_t * er, u_char * buf, int bufSize) { + + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + for (i = 0;i < er->eroLength;i++) { + + switch(er->eroType[i]) { + case RSVP_ERO_TYPE_IPV4: + size = rsvpteEncodeExplicitRoute4(&er->ero[i], buf, bufSize); + break; + case RSVP_ERO_TYPE_IPV6: + size = rsvpteEncodeExplicitRoute6(&er->ero[i], buf, bufSize); + break; + case RSVP_ERO_TYPE_ASN: + size = rsvpteEncodeExplicitRouteAsn(&er->ero[i], buf, bufSize); + break; + default: + return RSVP_ENC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + encodeSize += size; + bufSize -= size; + buf += size; + } + + session->hdr.length = encodeSize; + session->hdr.class = RSVP_EXPLICIT_ROUTE_CLASS; + session->hdr.cType = RSVP_EXPLICIT_ROUTE_CTYPE; + size = rsvpteEncodeObjectHeader(&session->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeExplicitRouteSubObjectHdr(rsvpExplicitRouteFlag_t * hdr, u_char * buf, int bufSize) { + u_short temp; + if (sizeof(u_short) > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(&temp, buf, sizeof(u_short)); + temp = ntohs(temp); + memcpy(hdr, &temp, sizeof(u_short)); + + return sizeof(u_short); +} + +int rsvpteDecodeExplicitRouteObject(rsvpExplicitRouteObject_t * er, u_char * buf, int bufSize) { + rsvpExplicitRouteFlag_t erFlag; + + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&session->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (session->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (session->hdr.class != RSVP_EXPLICIT_ROUTE_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + while (decodeSize < session->hdr.length) { + result = rsvpteDecodeExplicitRouteSubObjectHdr(&erFlag, buf, bufSize); + + switch(erFlag.type) { + case RSVP_ERO_TYPE_IPV4: + size = rsvpteDecodeExplicitRoute4(&er->ero[i], buf, bufSize); + break; + case RSVP_ERO_TYPE_IPV6: + size = rsvpteDecodeExplicitRoute6(&er->ero[i], buf, bufSize); + break; + case RSVP_ERO_TYPE_ASN: + size = rsvpteDecodeExplicitRouteAsn(&er->ero[i], buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + er->eroType[i] = erFlag.type; + + if (size < 0) { + return size; + } + + decodeSize += size; + bufSize -= size; + buf += size; + i++; + } + er->erLength = i; + + return decodeSize; +} + +/* Label Request Object */ + +int rsvpteEncodeLabelReqGeneric(rsvpLabelReqGeneric_t * gen, u_char * buf, int bufSize) { + rsvpLabelReqGeneric_t genCopy; + if (RSVP_LABELREQ_GENERIC_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + genCopy.reserved = htons(gen->reserved); + genCopy.l3pid = htons(gen->l3pid); + + memcpy(buf, &genCopy, RSVP_LABELREQ_GENERIC_SIZE); + + return RSVP_LABELREQ_GENERIC_SIZE; +} + +int rsvpteDecodeLabelReqGeneric(rsvpLabelReqGeneric_t * gen, u_char * buf, int bufSize) { + if (RSVP_LABELREQ_GENERIC_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(er, buf, RSVP_LABELREQ_GENERIC_SIZE); + gen->genCopy.reserved = ntohs(gen->genCopy.reserved); + gen->genCopy.l3pid = ntohs(gen->genCopy.l3pid); + + return RSVP_LABELREQ_GENERIC_SIZE; +} + +int rsvpteEncodeLabelReqAtm(rsvpLabelReqAtm_t * atm, u_char * buf, int bufSize) { + rsvpLabelReqAtm_t atmCopy; + if (RSVP_LABELREQ_ATM_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + atmCopy.reserved = htons(atm->reserved); + atmCopy.l3pid = htons(atm->l3pid); + + atmCopy.minFlags.mark = htons(atm->minFlags.mark); + atmCopy.minVci = htons(atm->minVci); + + atmCopy.maxFlags.mark = htons(atm->maxFlags.mark); + atmCopy.maxVci = htons(atm->maxVci); + + memcpy(buf, &atmCopy, RSVP_LABELREQ_ATM_SIZE); + + return RSVP_LABELREQ_ATM_SIZE; +} + +int rsvpteDecodeLabelReqAtm(rsvpLabelReqAtm_t * atm, u_char * buf, int bufSize) { + if (RSVP_LABELREQ_ATM_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(atm, buf, RSVP_LABELREQ_ATM_SIZE); + + atm->reserved = htons(atm->reserved); + atm->l3pid = htons(atm->l3pid); + + atm->minFlags.mark = htons(atm->minFlags.mark); + atm->minVci = htons(atm->minVci); + + atm->maxFlags.mark = htons(atm->maxFlags.mark); + atm->maxVci = htons(atm->maxVci); + + return RSVP_LABELREQ_ATM_SIZE; +} + +int rsvpteEncodeLabelReqFr(rsvpLabelReqFr_t * fr, u_char * buf, int bufSize) { + rsvpLabelReqFr_t frCopy; + if (RSVP_LABELREQ_FR_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + frCopy.reserved = htons(fr->reserved); + frCopy.l3pid = htons(fr->l3pid); + + frCopy.minFlags.mark = htons(fr->minFlags.mark); + frCopy.maxFlags.mark = htons(fr->maxFlags.mark); + + memcpy(buf, &frCopy, RSVP_LABELREQ_FR_SIZE); + + return RSVP_LABELREQ_FR_SIZE; +} + +int rsvpteDecodeLabelReqFr(rsvpLabelReqFr_t * fr, u_char * buf, int bufSize) { + if (RSVP_LABELREQ_FR_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(fr, buf, RSVP_LABELREQ_FR_SIZE); + + fr->reserved = htons(fr->reserved); + fr->l3pid = htons(fr->l3pid); + + fr->minFlags.mark = htons(fr->minFlags.mark); + fr->maxFlags.mark = htons(fr->maxFlags.mark); + + return RSVP_LABELREQ_FR_SIZE; +} + +int rsvpteEncodeLabelRequestObject(rsvpLabelRequestObject_t * req, u_char * buf, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(req->hdr.cType) { + case RSVP_LABEL_REQUEST_CTYPE_GENERIC: + size = rsvpteEncodeLabelReqGeneric(&req->u.generic, buf, bufSize); + break; + case RSVP_LABEL_REQUEST_CTYPE_ATM: + size = rsvpteEncodeLabelReqAtm(&req->u.atm, buf, bufSize); + break; + case RSVP_LABEL_REQUEST_CTYPE_FR: + size = rsvpteEncodeLabelReqFr(&req->u.fr, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + encodeSize += size; + + req->hdr.length = encodeSize; + req->hdr.class = RSVP_LABEL_REQUEST_CLASS; + size = rsvpteEncodeObjectHeader(&req->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeLabelRequestObject(rsvpLabelRequestObject_t * req, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&req->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (req->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (req->hdr.class != RSVP_LABEL_REQUEST_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(req->hdr.cType) { + case RSVP_LABEL_REQUEST_CTYPE_GENERIC: + size = rsvpteDecodeLabelReqGeneric(&req->u.generic, buf, bufSize); + break; + case RSVP_LABEL_REQUEST_CTYPE_ATM: + size = rsvpteDecodeLabelReqAtm(&req->u.atm, buf, bufSize); + break; + case RSVP_LABEL_REQUEST_CTYPE_FR: + size = rsvpteDecodeLabelReqFr(&req->u.fr, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +/* Session Attribute Object */ + +int rsvpteEncodeSessionAttribLspTunnel(rsvpSessionAttribLspTunnel_t * lsp, u_char * buf, int bufSize) { + int size = RSVP_SESSION_ATTRIB_LSP_TUNNEL_BASE_SIZE + lsp->nameLen; + + if (size > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + memcpy(buf, lsp, size); + + return size; +} + +int rsvpteDecodeSessionAttribLspTunnel(rsvpSessionAttribLspTunnel_t * lsp, u_char * buf, int bufSize) { + if (RSVP_SESSION_ATTRIB_LSP_TUNNEL_BASE_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(lsp, buf, RSVP_SESSION_ATTRIB_LSP_TUNNEL_BASE_SIZE); + if (lsp->nameLen > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(lsp->name, buf, lsp->nameLen); + + return RSVP_SESSION_ATTRIB_LSP_TUNNEL_BASE_SIZE + lsp->nameLen; +} + +int rsvpteEncodeSessionAttribLspTunnelRa(rsvpSessionAttribLspTunnelRa_t * lsp, u_char * buf, int bufSize) { + rsvpSessionAttribLspTunnelRa_t lspCopy; + int size = RSVP_SESSION_ATTRIB_LSP_TUNNEL_RA_BASE_SIZE + lsp->nameLen; + + if (size > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + lspCopy = *lsp; + lspCopy.excludeAny = htonl(lspCopy.excludeAny); + lspCopy.includeAny = htonl(lspCopy.includeAny); + lspCopy.includeAll = htonl(lspCopy.includeAll); + memcpy(buf, &lspCopy, size); + + return size; +} + +int rsvpteDecodeSessionAttribLspTunnelRa(rsvpSessionAttribLspTunnelRa_t * lsp, u_char * buf, int bufSize) { + if (RSVP_SESSION_ATTRIB_LSP_TUNNEL_RA_BASE_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + memcpy(lsp, buf, RSVP_SESSION_ATTRIB_LSP_TUNNEL_RA_BASE_SIZE); + + if (lsp->nameLen > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + memcpy(lsp->name, buf, lsp->nameLen); + + lsp->excludeAny = ntohl(lsp->excludeAny); + lsp->includeAny = ntohl(lsp->includeAny); + lsp->includeAll = ntohl(lsp->includeAll); + + return RSVP_SESSION_ATTRIB_LSP_TUNNEL_BASE_SIZE + lsp->nameLen; +} + +int rsvpteEncodeSessionAttribObject(rsvpSessionAttibObject_t * session, u_char * buf, int bufSize) { + + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(session->hdr.cType) { + case RSVP_SESSION_ATTRIB_CTYPE_LSP_TUNNEL: + size = rsvpteEncodeSessionAttribLspTunnel(&session->u.tunnel, buf, bufSize); + break; + case RSVP_SESSION_ATTRIB_CLASS_LSP_TUNNEL_RA: + size = rsvpteEncodeSessionAttribLspTunnelRa(&session->u.tunnelRa, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + if (size < 0) { + return size; + } + + encodeSize += size; + + session->hdr.length = encodeSize; + session->hdr.class = RSVP_SESSION_ATTRIB_CLASS; + size = rsvpteEncodeObjectHeader(&session->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeSessionAttribObject(rsvpSessionAttibObject_t * session, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&session->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (session->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (session->hdr.class != RSVP_SESSION_ATTRIB_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(session->hdr.cType) { + case RSVP_SESSION_ATTRIB_CTYPE_LSP_TUNNEL: + size = rsvpteDecodeSessionAttribLspTunnel(&session->u.tunnel, buf, bufSize); + break; + case RSVP_SESSION_ATTRIB_CLASS_LSP_TUNNEL_RA: + size = rsvpteDecodeSessionAttribLspTunnelRa(&session->u.tunnelRa, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +/* Filter Spec Object */ + +int rsvpteEncodeFilterSpec4(rsvpFilterSpec4_t * filter, u_char * buf, int bufSize) { + rsvpFilterSpec4_t filterCopy; + + if (RSVP_FILTER_SPEC4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + filterCopy.sourceAddr = htonl(filter->sourceAddr); + filterCopy.sourcePort = htons(filter->sourcePort); + filterCopy.reserved = filter->reserved = 0; + + memcpy(buf, &filterCopy, RSVP_FILTER_SPEC4_SIZE); + + return RSVP_FILTER_SPEC4_SIZE; +} + +int rsvpteDecodeFilterSpec4(rsvpFilterSpec4_t * filter, u_char * buf, int bufSize) { + if (RSVP_FILTER_SPEC4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(filter, buf, RSVP_FILTER_SPEC4_SIZE); + filter->sourceAddr = ntohl(filter->sourceAddr); + filter->sourcePort = ntohs(filter->sourcePort); + filter->reserved = 0; + + return RSVP_FILTER_SPEC4_SIZE; +} + +int rsvpteEncodeFilterSpec6(rsvpFilterSpec6_t * filter, u_char * buf, int bufSize) { + rsvpFilterSpec6_t filterCopy; + + if (RSVP_FILTER_SPEC6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + memcpy(filterCopy.sourceAddr, filter->sourceAddr, RSVP_IPV6_ADDR_LEN); + filterCopy.sourcePort = htons(filter->sourcePort); + filterCopy.reserved = filter->reserved = 0; + + memcpy(buf, &filterCopy, RSVP_FILTER_SPEC6_SIZE); + + return RSVP_FILTER_SPEC6_SIZE; +} + +int rsvpteDecodeFilterSpec6(rsvpFilterSpec6_t * filter, u_char * buf, int bufSize) { + if (RSVP_FILTER_SPEC6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(filter, buf, RSVP_FILTER_SPEC6_SIZE); + filter->sourcePort = ntohs(filter->sourcePort); + filter->reserved = 0; + + return RSVP_FILTER_SPEC6_SIZE; +} + +int rsvpteEncodeFilterSpecFlow(rsvpFilterSpecFlow_t * filter, u_char * buf, int bufSize) { + rsvpFilterSpecFlow_t filterCopy; + + if (RSVP_FILTER_SPEC_FLOW_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + memcpy(filterCopy.sourceAddr, filter->sourceAddr, RSVP_IPV6_ADDR_LEN); + filterCopy.flag.mark = htonl(filter->flag.mark); + + memcpy(buf, &filterCopy, RSVP_FILTER_SPEC_FLOW_SIZE); + + return RSVP_FILTER_SPEC_FLOW_SIZE; +} + +int rsvpteDecodeFilterSpecFlow(rsvpFilterSpecFlow_t * filter, u_char * buf, int bufSize) { + if (RSVP_FILTER_SPEC_FLOW_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(filter, buf, RSVP_FILTER_SPEC_FLOW_SIZE); + filter->flag.mark = ntohl(filter->flag.mark); + + return RSVP_FILTER_SPEC_FLOW_SIZE; +} + +int rsvpteEncodeFilterSpecObject(rsvpFilterSpec_t * filter, u_char * buf, int bufSize) { + + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(filter->hdr.cType) { + case RSVP_FILTER_SPEC_CTYPE_IPV4: + size = rsvpteEncodeFilterSpec4(&filter->u.ipv4, buf, bufSize); + break; + case RSVP_FILTER_SPEC_CTYPE_IPV6: + size = rsvpteEncodeFilterSpec6(&filter->u.ipv6, buf, bufSize); + break; + case RSVP_FILTER_SPEC_CTYPE_FLOW: + size = rsvpteEncodeFilterSpecFlow(&filter->u.flow, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + encodeSize += size; + + filter->hdr.length = encodeSize; + filter->hdr.class = RSVP_FILTER_SPEC_CLASS; + size = rsvpteEncodeObjectHeader(&filter->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeFilterSpecObject(rsvpFilterSpec_t * filter, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&filter->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (filter->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (filter->hdr.class != RSVP_FILTER_SPEC_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(filter->hdr.cType) { + case RSVP_FILTER_SPEC_CTYPE_IPV4: + size = rsvpteDecodeFilterSpec4(&filter->u.ipv4, buf, bufSize); + break; + case RSVP_FILTER_SPEC_CTYPE_IPV6: + size = rsvpteDecodeFilterSpec6(&filter->u.ipv6, buf, bufSize); + break; + case RSVP_FILTER_SPEC_CTYPE_FLOW: + size = rsvpteDecodeFilterSpecFlow(&filter->u.flow, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +/* Sender Template Object */ + +int rsvpteEncodeSenderTemplateTunnel4(rsvpSenderTemplateTunnel4_t * sender, u_char * buf, int bufSize) { + rsvpSenderTemplateTunnel4_t senderCopy; + + if (RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + senderCopy.sender = htonl(sender->sender); + senderCopy.reserved = 0; + senderCopy.lspId = htons(sender->lspId); + + memcpy(buf, &senderCopy, RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE); + + return RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE; +} + +int rsvpteDecodeSenderTemplateTunnel4(rsvpSenderTemplateTunnel4_t * sender, u_char * buf, int bufSize) { + if (RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(sender, buf, RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE); + sender->sender = ntohl(sender->sender); + sender->reserved = 0; + sender->lspId = ntohs(sender->lspId); + + return RSVP_SENDER_TEMPLATE_TUNNEL4_SIZE; +} + +int rsvpteEncodeSenderTemplateTunnel6(rsvpSenderTemplateTunnel4 * sender, u_char * buf, int bufSize) { + rsvpSenderTemplateTunnel6_t senderCopy; + + if (RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + memcpy(senderCopy.sender, sender->sender, RSVP_IPV6_ADDR_LEN); + senderCopy.reserved = 0; + senderCopy.lspId = htons(sender->lspId); + + memcpy(buf, &senderCopy, RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE); + + return RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE; +} + +int rsvpteDecodeSenderTemplateTunnel6(rsvpFilterSpecFlow_t * sender, u_char * buf, int bufSize) { + if (RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(sender, buf, RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE); + sender->lspId = ntohs(sender->lspId); + + return RSVP_SENDER_TEMPLATE_TUNNEL6_SIZE; +} + +int rsvpteEncodeSenderTemplateObject(rsvpSenderTemplate_t * sender, u_char * buf, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + switch(sender->hdr.cType) { + case RSVP_SENDER_TEMPLATE_CTYPE_IPV4: + size = rsvpteEncodeSenderTemplate4(&sender->u.ipv4, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_IPV6: + size = rsvpteEncodeSenderTemplate6(&sender->u.ipv6, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_FLOW: + size = rsvpteEncodeSenderTemplateFlow(&sender->u.flow, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_TUNNEL4: + size = rsvpteEncodeSenderTemplateTunnel4(&sender->u.tunnel4, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_TUNNEL6: + size = rsvpteEncodeSenderTemplateTunnel6(&sender->u.tunnel6, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + encodeSize += size; + + sender->hdr.length = encodeSize; + sender->hdr.class = RSVP_SENDER_TEMPLATE_CLASS; + size = rsvpteEncodeObjectHeader(&sender->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeSenderTemplateObject(rsvpSenderTemplate_t * sender, u_char * buf, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&sender->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (sender->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (sender->hdr.class != RSVP_SENDER_TEMPLATE_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + switch(sender->hdr.cType) { + case RSVP_SENDER_TEMPLATE_CTYPE_IPV4: + size = rsvpteDecodeSenderTemplate4(&sender->u.ipv4, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_IPV6: + size = rsvpteDecodeSenderTemplate6(&sender->u.ipv6, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_FLOW: + size = rsvpteDecodeSenderTemplateFlow(&sender->u.flow, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_TUNNEL4: + size = rsvpteDecodeSenderTemplateTunnel4(&sender->u.tunnel4, buf, bufSize); + break; + case RSVP_SENDER_TEMPLATE_CTYPE_TUNNEL6: + size = rsvpteDecodeSenderTemplateTunnel6(&sender->u.tunnel6, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + if (size < 0) { + return size; + } + + return decodeSize + size; +} + +/* Record Route Object */ + +int rsvpteEncodeRecordRoute4(rsvpRecordRoute4_t * rr, u_char * buf, int bufSize) { + rsvpRecordRoute4_t rrCopy; + + if (RSVP_RECORD_ROUTE4_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + rrCopy = *rr; + rrCopy.type = RSVP_RECORD_ROUTE_TYPE_IPV4; + rrCopy.length = RSVP_RECORD_ROUTE4_SIZE; + htonl_nba(&rrCopy.addressMsb, NULL); + + memcpy(buf, &rrCopy, RSVP_RECORD_ROUTE4_SIZE); + + return RSVP_RECORD_ROUTE4_SIZE; +} + +int rsvpteDecodeRecordRoute4(rsvpRecordRoute4_t * sender, u_char * buf, int bufSize) { + if (RSVP_RECORD_ROUTE4_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(rr, buf, RSVP_RECORD_ROUTE4_SIZE); + ntohl_nba(rr->addressMsb, NULL); + + return RSVP_RECORD_ROUTE4_SIZE; +} + +int rsvpteEncodeRecordRoute6(rsvpRecordRoute6_t * rr, u_char * buf, int bufSize) { + rsvpRecordRoute6_t rrCopy; + + if (RSVP_RECORD_ROUTE6_SIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + rrCopy = *rr; + rrCopy.type = RSVP_RECORD_ROUTE_TYPE_IPV6; + rrCopy.length = RSVP_RECORD_ROUTE6_SIZE; + + memcpy(buf, &rrCopy, RSVP_RECORD_ROUTE6_SIZE); + + return RSVP_RECORD_ROUTE6_SIZE; +} + +int rsvpteDecodeRecordRoute6(rsvpRecordRoute6_t * sender, u_char * buf, int bufSize) { + if (RSVP_RECORD_ROUTE6_SIZE > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(rr, buf, RSVP_RECORD_ROUTE6_SIZE); + + return RSVP_RECORD_ROUTE6_SIZE; +} + +int rsvpteEncodeRecordRouteLabel(rsvpRecordRouteLabel_t * rr, u_char * buf, int bufSize) { + rsvpRecordRouteLabel_t rrCopy; + int size; + + if (4 > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + if ((size = rsvpteEncodeLabelObject(&rr->label, buf + 4, bufSize - 4)) < 0) { + return size; + } + + rrCopy = *rr; + rrCopy.type = RSVP_RECORD_ROUTE_TYPE_LABEL; + rrCopy.length = 4 + size; + rrCopy.cType = rr->label.hdr.cType; + + memcpy(buf, &rrCopy, 4); + + return 4 + size; +} + +int rsvpteDecodeRecordRouteLabel(rsvpRecordRouteLabel_t * sender, u_char * buf, int bufSize) { + int size; + if (4 > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + memcpy(rr, buf, 4); + size = rsvpteDecodeLabelObject(&rr->label, buf + 4, bufSize - 4; + + return 4 + size; +} + +int rsvpteEncodeRecordRouteObject(rsvpRecordRouteObject_t * rr, char * bug, int bufSize) { + int encodedSize = 0; + char *bufHdr = buf; + int size; + in i; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + for (i = 0, i < = rr->rrLen, i++) { + switch(rr->rrType[i]) { + case RSVP_RECORD_ROUTE_TYPE_IPV4: + size = rsvpteEncodeRecordRoute4(&rr->rr[i].ipv4, buf, bufSize); + break; + case RSVP_RECORD_ROUTE_TYPE_IPV6: + size = rsvpteEncodeRecordRoute6(&rr->rr[i].ipv6, buf, bufSize); + break; + case RSVP_RECORD_ROUTE_TYPE_LABEL: + size = rsvpteEncodeRecordRouteLabel(&rr->rr[i].label, buf, bufSize); + break; + default: + return RSVP_ENC_OBJECTERROR; + } + if (size < 0) { + return size; + } + encodeSize += size; + bufSize -= size; + buf += size; + } + + rr->hdr.length = encodeSize; + rr->hdr.class = RSVP_RECORD_ROUTE_CLASS; + size = rsvpteEncodeObjectHeader(&rr->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeRecordRouteObject(rsvpRecordRouteObject_t * rr, char * bug, int bufSize) { + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&rr->hdr, buf, bufSize); + int i; + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (rr->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (rr->hdr.class != RSVP_RECORD_ROUTE_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + + while (decodeSize < rr->hdr.length) { + switch(buf[0]) { + case RSVP_RECORD_ROUTE_TYPE_IPV4: + size = rsvpteDecodeRecordRoute4(&rr->rr[i].ipv4, buf, bufSize); + break; + case RSVP_RECORD_ROUTE_TYPE_IPV6: + size = rsvpteDecodeRecordRoute6(&rr->rr[i].ipv6, buf, bufSize); + break; + case RSVP_RECORD_ROUTE_TYPE_LABEL: + size = rsvpteDecodeRecordRouteLabel(&rr->rr[i].label, buf, bufSize); + break; + default: + return RSVP_DEC_OBJECTERROR; + } + + if (size < 0) { + return RSVP_DEC_OBJECTERROR; + } + + decodeSize += size; + bufSize -= size; + buf += size; + i++; + } + rr->rrLen = i; + + return decodeSize; +} + +/* Sender TSpec Object */ + +int rsvpteEncodeSenderTSpectObject(rsvpSenderTSpecObject_t * sender, char * bug, int bufSize) { + + int encodedSize = 0; + char *bufHdr = buf; + int size; + + if (RSVP_OBJECT_HDRSIZE > bufSize) { + return MPLS_ENC_BUFFTOOSMALL; + } + + size = RSVP_OBJECT_HDRSIZE; + encodeSize += size; + bufSize -= size; + buf += size; + + /* need TSpec Definition */ + + if (size < 0) { + return size; + } + + encodeSize += size; + + sender->hdr.length = encodeSize; + sender->hdr.class = RSVP_SENDER_TSPEC_CLASS; + size = rsvpteEncodeObjectHeader(&sender->hdr, bufHdr, RSVP_OBJECT_HDRSIZE); if (size < 0) { + return size; + } + + return encodeSize; +} + +int rsvpteDecodeSenderTSpecObject(rsvpSenderTSpecObject_t * req, char * bug, int bufSize) { + + int decodedSize = 0; + int size = rsvpteDecodeObjectHeader(&sender->hdr, buf, bufSize); + + if (size < 0) { + return size; + } + decodeSize += size; + bufSize -= size; + buf += size; + + if (sender->hdr.length > bufSize) { + return MPLS_DEC_BUFFTOOSMALL; + } + + if (sender->hdr.class != RSVP_SENDER_TSPEC_CLASS) { + return RSVP_DEC_OBJECTERROR; + } + /* need TSpec definitiion */ + + if (size < 0) { + return size; + } + + return decodeSize + size; +} -- 2.11.4.GIT